package com.lingyun.mqttserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lingyun.mqttserver.dao.mapper.*;
import com.lingyun.mqttserver.dao.pojo.*;
import com.lingyun.mqttserver.service.ManageDataService;
import com.lingyun.mqttserver.util.ModbusAddressUtil;
import com.lingyun.mqttserver.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ManageDataServiceImpl implements ManageDataService {

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private DeviceInfoMapper deviceInfoMapper;

    @Autowired
    private DeviceTypeMapper deviceTypeMapper;


    @Autowired
    private DeviceDataLogMapper deviceDataLogMapper;

    @Autowired
    private DeviceGroupMapper deviceGroupMapper;
    @Autowired
    private DeviceGroupMappingMapper deviceGroupMappingMapper;
    @Autowired
    private LowerComputerVariableMapper lowerComputerVariableMapper;
    @Autowired
    private DeviceTypeVariableTemplateMapper deviceTypeVariableTemplateMapper;
    @Autowired
    private MqttScreenVariableMappingMapper mqttScreenVariableMappingMapper;
    @Autowired
    private ScreenConnectionMapper screenConnectionMapper;
    @Autowired
    private MqttScreenVariableMappingVariableMapper mqttScreenVariableMappingVariableMapper;

    @Override
    public Result projectList() {
        List<Project> projects = projectMapper.selectList(null);

        // 查询所有设备并按项目分组
        List<DeviceInfo> allDevices = deviceInfoMapper.selectList(null);
        Map<Integer, Long> deviceCountMap = allDevices.stream()
                .collect(Collectors.groupingBy(DeviceInfo::getProjectId, Collectors.counting()));

        // 构建响应数据
        List<Map<String, Object>> result = projects.stream().map(project -> {
            Map<String, Object> item = new HashMap<>();
            item.put("id", project.getId());
            item.put("projectName", project.getProjectName());  // 注意：你的字段是name不是projectName
            item.put("topic", project.getTopic());
            item.put("createTime", project.getCreateTime());
            item.put("deviceCount", deviceCountMap.getOrDefault(project.getId(), 0L));
            return item;
        }).collect(Collectors.toList());


        return Result.success(result);
    }

    /**
     * 根据项目ID查询设备数量
     */
    public Long getDeviceCountByProjectId(Integer projectId) {
        if (projectId == null) {
            return 0L;
        }
        LambdaQueryWrapper<DeviceInfo> query = new LambdaQueryWrapper<>();
        query.eq(DeviceInfo::getProjectId, projectId);
        return deviceInfoMapper.selectCount(query);
    }

    @Override
    public Result projectAdd(Project project) {

        // 参数校验
        if (project == null) {
            return Result.fail(400, "项目信息不能为空");
        }

        // 必填字段校验
        if (StringUtils.isBlank(project.getProjectName())) {
            return Result.fail(400, "项目名称不能为空");
        }

        if (StringUtils.isBlank(project.getTopic())) {
            return Result.fail(400, "项目Topic不能为空");
        }

        // 字段长度校验
        if (project.getProjectName().length() > 50) {
            return Result.fail(400, "项目名称长度不能超过50个字符");
        }

        if (project.getTopic().length() > 100) {
            return Result.fail(400, "项目Topic长度不能超过100个字符");
        }

        // Topic格式校验（只能包含字母、数字、下划线、短横线）
        if (!project.getTopic().matches("^[a-zA-Z0-9_-]+$")) {
            return Result.fail(400, "项目Topic只能包含字母、数字、下划线和短横线");
        }

        try {
            // 检查项目名称是否已存在
            LambdaQueryWrapper<Project> nameQuery = new LambdaQueryWrapper<>();
            nameQuery.eq(Project::getProjectName, project.getProjectName());
            Long nameCount = projectMapper.selectCount(nameQuery);
            if (nameCount > 0) {
                return Result.fail(400, "项目名称已存在");
            }

            // 检查Topic是否已存在
            LambdaQueryWrapper<Project> topicQuery = new LambdaQueryWrapper<>();
            topicQuery.eq(Project::getTopic, project.getTopic());
            Long topicCount = projectMapper.selectCount(topicQuery);
            if (topicCount > 0) {
                return Result.fail(400, "项目Topic已存在");
            }

            // 创建新项目对象
            Project newProject = new Project();
            newProject.setProjectName(project.getProjectName());  // 注意：你的实体类字段是name
            newProject.setTopic(project.getTopic());
            newProject.setInfo(project.getInfo());  // 可选信息
            newProject.setCreateTime(new Timestamp(System.currentTimeMillis()));  // 设置创建时间

            // 执行插入
            int result = projectMapper.insert(newProject);

            if (result > 0) {
                // 返回成功响应，包含新创建的项目ID
                Map<String, Object> data = new HashMap<>();
                data.put("id", newProject.getId());
                data.put("projectName", newProject.getProjectName());
                data.put("topic", newProject.getTopic());
                data.put("createTime", newProject.getCreateTime());
                data.put("deviceCount", 0);
                return Result.success(data);
            } else {
                return Result.fail(500, "项目创建失败");
            }

        } catch (DuplicateKeyException e) {
            log.error("项目插入重复键异常: {}", e.getMessage());
            return Result.fail(400, "项目名称或Topic已存在");
        } catch (DataIntegrityViolationException e) {
            log.error("项目数据完整性异常: {}", e.getMessage());
            return Result.fail(400, "数据格式不正确");
        } catch (Exception e) {
            log.error("项目创建系统异常: {}", e.getMessage(), e);
            return Result.fail(500, "系统异常，请稍后重试");
        }
    }

    @Override
    public Result projectUpdate(Project project) {
        // 参数校验
        if (project == null) {
            return Result.fail(400, "项目信息不能为空");
        }

        if (project.getId() == null) {
            return Result.fail(400, "项目ID不能为空");
        }

        if (StringUtils.isBlank(project.getProjectName())) {
            return Result.fail(400, "项目名称不能为空");
        }

        if (StringUtils.isBlank(project.getTopic())) {
            return Result.fail(400, "项目Topic不能为空");
        }

        // 字段长度校验
        if (project.getProjectName().length() > 50) {
            return Result.fail(400, "项目名称长度不能超过50个字符");
        }

        if (project.getTopic().length() > 100) {
            return Result.fail(400, "项目Topic长度不能超过100个字符");
        }

        try {
            // 检查项目是否存在
            Project existingProject = projectMapper.selectById(project.getId());
            if (existingProject == null) {
                return Result.fail(404, "项目不存在");
            }

            // 检查项目名称是否被其他项目使用（排除当前项目）
            LambdaQueryWrapper<Project> nameQuery = new LambdaQueryWrapper<>();
            nameQuery.eq(Project::getProjectName, project.getProjectName())
                    .ne(Project::getId, project.getId());
            Long nameCount = projectMapper.selectCount(nameQuery);
            if (nameCount > 0) {
                return Result.fail(400, "项目名称已被其他项目使用");
            }

            // 检查Topic是否被其他项目使用（排除当前项目）
            LambdaQueryWrapper<Project> topicQuery = new LambdaQueryWrapper<>();
            topicQuery.eq(Project::getTopic, project.getTopic())
                    .ne(Project::getId, project.getId());
            Long topicCount = projectMapper.selectCount(topicQuery);
            if (topicCount > 0) {
                return Result.fail(400, "项目Topic已被其他项目使用");
            }

            // 构建更新对象
            Project updateProject = new Project();
            updateProject.setId(project.getId());
            updateProject.setProjectName(project.getProjectName());
            updateProject.setTopic(project.getTopic());
            updateProject.setInfo(project.getInfo()); // 更新可选信息

            // 执行更新
            int result = projectMapper.updateById(updateProject);

            if (result > 0) {
                // 查询更新后的完整项目信息（包含设备数量）
                HashMap<String, Object> projectVo = new HashMap<>();
                projectVo.put("id", project.getId());
                projectVo.put("projectName", project.getProjectName());
                projectVo.put("topic", project.getTopic());
                projectVo.put("createTime", project.getCreateTime());
                projectVo.put("deviceCount", getDeviceCountByProjectId(project.getId()));
                return Result.success(projectVo);
            } else {
                return Result.fail(500, "项目更新失败");
            }

        } catch (DuplicateKeyException e) {
            log.error("项目更新重复键异常: {}", e.getMessage());
            return Result.fail(400, "项目名称或Topic已被使用");
        } catch (Exception e) {
            log.error("项目更新系统异常: {}", e.getMessage(), e);
            return Result.fail(500, "系统异常，请稍后重试");
        }
    }

    @Override
    public Result projectDelete(Integer id) {
        try{
            projectMapper.deleteById(id);
        } catch (Exception e) {
            return Result.fail(400, "该项目下还有设备，无法删除");
        }
        return Result.success(null);
    }

    @Override
    public Result deviceTypeList(Integer projectId, String keyword, Integer page, Integer pageSize) {
        try {
            // 设置分页
            if (page == null || page < 1) page = 1;
            if (pageSize == null || pageSize < 1) pageSize = 10;

            // 查询所有设备类型
            List<DeviceType> deviceTypes = deviceTypeMapper.selectList(null);


            // 查询所有设备
            List<DeviceInfo> allDevices = deviceInfoMapper.selectList(null);

            // 构建结果列表
            List<Map<String, Object>> resultList = new ArrayList<>();

            for (DeviceType deviceType : deviceTypes) {
                // 计算该类型下的设备数量
                int deviceCount = 0;
                for (DeviceInfo device : allDevices) {
                    // 如果指定了项目ID，要匹配项目ID和设备类型
                    if (projectId != null) {
                        if (Objects.equals(device.getDeviceType(), deviceType.getId()) &&
                                Objects.equals(device.getProjectId(), projectId)) {
                            deviceCount++;
                        }
                    } else {
                        // 不指定项目ID，只匹配设备类型
                        if (Objects.equals(device.getDeviceType(), deviceType.getId())) {
                            deviceCount++;
                        }
                    }
                }

//                // 如果指定了项目ID且设备数量为0，跳过
//                if (projectId != null && deviceCount == 0) {
//                    continue;
//                }

                // 关键词筛选
                if (keyword != null && !keyword.isEmpty()) {
                    String typeName = deviceType.getTypeName();
                    String info = deviceType.getInfo();
                    if ((typeName == null || !typeName.contains(keyword)) &&
                            (info == null || !info.contains(keyword))) {
                        continue;
                    }
                }

                // 构建返回数据
                Map<String, Object> item = new HashMap<>();
                item.put("id", deviceType.getId());
                item.put("typeName", deviceType.getTypeName());
                item.put("description", deviceType.getInfo());
                item.put("deviceType", deviceType.getDeviceType());
                item.put("deviceCount", deviceCount);
                item.put("projectId", deviceType.getProjectId());
                String timeString = formatTime(deviceType.getCreateTime());
                item.put("createTime", timeString);
                resultList.add(item);
            }

            // 分页处理
            int total = resultList.size();
            int start = (page - 1) * pageSize;
            int end = Math.min(start + pageSize, total);

            if (start >= total) {
                resultList = new ArrayList<>();
            } else {
                resultList = resultList.subList(start, end);
            }

            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", resultList);
            result.put("total", total);
            result.put("page", page);
            result.put("pageSize", pageSize);

            return Result.success(result);

        } catch (Exception e) {
            log.error("获取设备类型列表失败: {}", e.getMessage());
            return Result.fail(500, "系统错误");
        }
    }

    @Override
    public Result deviceTypeAdd(DeviceType deviceType) {
        try {
            // 检查必填字段
            if (deviceType == null) {
                return Result.fail(400, "设备类型信息不能为空");
            }
            if (deviceType.getProjectId() == null) {
                return Result.fail(400, "项目ID不能为空");
            }
            if (deviceType.getTypeName() == null || deviceType.getTypeName().trim().isEmpty()) {
                return Result.fail(400, "设备类型名称不能为空");
            }

            // 设置创建时间
            deviceType.setCreateTime(new Timestamp(System.currentTimeMillis()));

            // 插入数据库
            int result = 0;
            try{
                result = deviceTypeMapper.insert(deviceType);
            }catch (Exception e){
                return Result.fail(500, "插入失败");
            }

            if (result > 0) {
                // 构建返回数据
                Map<String, Object> data = new HashMap<>();
                data.put("id", deviceType.getId());
                data.put("projectId", deviceType.getProjectId());
                data.put("typeName", deviceType.getTypeName());
                data.put("deviceType", deviceType.getDeviceType());
                data.put("description", deviceType.getInfo()); // 使用info字段作为description
                data.put("createTime", formatTime(deviceType.getCreateTime()));
                data.put("deviceCount", 0); // 新添加的类型设备数量为0

                return Result.success(data);
            } else {
                return Result.fail(500, "添加设备类型失败");
            }

        } catch (Exception e) {
            log.error("添加设备类型异常: {}", e.getMessage());
            return Result.fail(500, "系统错误");
        }
    }

    // 时间格式化方法
    private String formatTime(Timestamp timestamp) {
        if (timestamp == null) return "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(timestamp);
    }

    @Override
    public Result deviceTypeUpdate(DeviceType deviceType) {
        try {
            // 检查必填字段
            if (deviceType == null) {
                return Result.fail(400, "设备类型信息不能为空");
            }
            if (deviceType.getId() == null) {
                return Result.fail(400, "设备类型ID不能为空");
            }
            if (deviceType.getProjectId() == null) {
                return Result.fail(400, "项目ID不能为空");
            }
            if (deviceType.getTypeName() == null || deviceType.getTypeName().trim().isEmpty()) {
                return Result.fail(400, "设备类型名称不能为空");
            }

            // 检查设备类型是否存在
            DeviceType existingType = deviceTypeMapper.selectById(deviceType.getId());
            if (existingType == null) {
                return Result.fail(404, "设备类型不存在");
            }

            // 更新数据库
            int result = deviceTypeMapper.updateById(deviceType);

            if (result > 0) {
                // 查询更新后的完整数据
                DeviceType updatedType = deviceTypeMapper.selectById(deviceType.getId());

                // 查询该类型下的设备数量
                LambdaQueryWrapper<DeviceInfo> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(DeviceInfo::getDeviceType, deviceType.getId());
                Long deviceCount = deviceInfoMapper.selectCount(queryWrapper);

                // 构建返回数据
                Map<String, Object> data = new HashMap<>();
                data.put("id", updatedType.getId());
                data.put("projectId", updatedType.getProjectId());
                data.put("typeName", updatedType.getTypeName());
                data.put("description", updatedType.getInfo());

                // 格式化创建时间
                if (updatedType.getCreateTime() != null) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    data.put("createTime", sdf.format(updatedType.getCreateTime()));
                } else {
                    data.put("createTime", "");
                }

                data.put("deviceCount", deviceCount);

                return Result.success(data);
            } else {
                return Result.fail(500, "更新设备类型失败");
            }

        } catch (Exception e) {
            log.error("更新设备类型异常: {}", e.getMessage());
            return Result.fail(500, "系统错误");
        }
    }




    @Override
    public Result DeviceAdd(DeviceInfo deviceInfo) {
        try {
            // 参数校验
            if (deviceInfo == null) {
                return Result.fail(400, "设备信息不能为空");
            }

            if (deviceInfo.getProjectId() == null) {
                return Result.fail(400, "项目ID不能为空");
            }

            if (deviceInfo.getDeviceType() == null) {
                return Result.fail(400, "设备类型不能为空");
            }

            if (deviceInfo.getDeviceName() == null || deviceInfo.getDeviceName().trim().isEmpty()) {
                return Result.fail(400, "设备名称不能为空");
            }

            if (deviceInfo.getHardwareAddress() == null || deviceInfo.getHardwareAddress().trim().isEmpty()) {
                return Result.fail(400, "硬件地址不能为空");
            }

            // 检查设备名称是否已存在
            LambdaQueryWrapper<DeviceInfo> nameQuery = new LambdaQueryWrapper<>();
            nameQuery.eq(DeviceInfo::getDeviceName, deviceInfo.getDeviceName().trim());
            nameQuery.eq(DeviceInfo::getProjectId, deviceInfo.getProjectId());
            if (deviceInfoMapper.selectCount(nameQuery) > 0) {
                return Result.fail(400, "设备名称已存在");
            }

            // 检查硬件地址是否已存在
            LambdaQueryWrapper<DeviceInfo> addressQuery = new LambdaQueryWrapper<>();
            addressQuery.eq(DeviceInfo::getHardwareAddress, deviceInfo.getHardwareAddress().trim());
            if (deviceInfoMapper.selectCount(addressQuery) > 0) {
                return Result.fail(400, "硬件地址已存在");
            }

            // 设置默认值
            deviceInfo.setStats(0); // 默认离线状态
            deviceInfo.setCreateTime(new Timestamp(System.currentTimeMillis()));

            // 保存设备信息
            int result = deviceInfoMapper.insert(deviceInfo);

            if (result > 0) {
                // 返回新增的设备信息（包含生成的ID）
                DeviceInfo savedDevice = deviceInfoMapper.selectById(deviceInfo.getId());
                return Result.success(savedDevice);
            } else {
                return Result.fail(500, "新增设备失败");
            }

        } catch (Exception e) {
            log.error("新增设备失败: {}", e.getMessage(), e);
            return Result.fail(500, "新增设备失败");
        }
    }

    @Override
    public Result deviceUpdate(DeviceInfo deviceInfo) {
        // 1. 参数校验
        if (deviceInfo.getId() == null) {
            return Result.fail(400, "设备ID不能为空");
        }
        if (deviceInfo.getProjectId() == null) {
            return Result.fail(400, "项目ID不能为空");
        }
        if (StringUtils.isBlank(deviceInfo.getDeviceName())) {
            return Result.fail(400, "设备名称不能为空");
        }

        // 2. 检查设备是否存在
        DeviceInfo existingDevice = deviceInfoMapper.selectById(deviceInfo.getId());
        if (existingDevice == null) {
            return Result.fail(400, "设备不存在");
        }

        // 3. 检查设备名称是否重复（排除自身）
        if (!existingDevice.getDeviceName().trim().equals(deviceInfo.getDeviceName().trim())) {
            LambdaQueryWrapper<DeviceInfo> nameQuery = new LambdaQueryWrapper<>();
            nameQuery.eq(DeviceInfo::getDeviceName, deviceInfo.getDeviceName().trim());
            nameQuery.eq(DeviceInfo::getProjectId, deviceInfo.getProjectId());
            nameQuery.ne(DeviceInfo::getId, deviceInfo.getId()); // 排除当前设备

            if (deviceInfoMapper.selectCount(nameQuery) > 0) {
                return Result.fail(400, "设备名称已存在");
            }
        }


        // 5. 执行更新操作
        int updateCount = deviceInfoMapper.updateById(deviceInfo);
        if (updateCount > 0) {
            return Result.success("设备更新成功");
        } else {
            return Result.fail(500, "设备更新失败");
        }
    }

    @Override
    public Result DeviceDelete(Integer id) {
        try {
            // 参数校验
            if (id == null) {
                return Result.fail(400, "设备ID不能为空");
            }

            // 检查设备是否存在
            DeviceInfo existingDevice = deviceInfoMapper.selectById(id);
            if (existingDevice == null) {
                return Result.fail(404, "设备不存在");
            }

            // 执行删除操作
            int result = deviceInfoMapper.deleteById(id);

            if (result > 0) {
                log.info("删除设备成功，设备ID: {}", id);
                return Result.success(null);
            } else {
                return Result.fail(500, "删除设备失败");
            }

        } catch (Exception e) {
            log.error("删除设备失败，设备ID: {}, 错误信息: {}", id, e.getMessage(), e);
            return Result.fail(500, "删除设备失败");
        }
    }






    /**
     * 检查字符串是否包含中文
     * @param str 要检查的字符串
     * @return 包含中文返回true，否则返回false
     */
    private boolean containsChinese(String str) {
        if (StringUtils.isBlank(str)) {
            return false;
        }
        // 使用正则表达式匹配中文字符
        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]");
        Matcher matcher = pattern.matcher(str);
        return matcher.find();
    }



    @Override
    public Result deviceTypeDelete(Integer deviceTypeId) {
        try {
            // 检查参数
            if (deviceTypeId == null) {
                return Result.fail(400, "设备类型ID不能为空");
            }

            // 检查设备类型是否存在
            DeviceType deviceType = deviceTypeMapper.selectById(deviceTypeId);
            if (deviceType == null) {
                return Result.fail(404, "设备类型不存在");
            }

            // 检查该类型下是否有设备
            LambdaQueryWrapper<DeviceInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DeviceInfo::getDeviceType, deviceTypeId);
            Long deviceCount = deviceInfoMapper.selectCount(queryWrapper);

            if (deviceCount > 0) {
                return Result.fail(400, "该设备类型下还有设备，无法删除");
            }

            // 执行删除
            int result = deviceTypeMapper.deleteById(deviceTypeId);

            if (result > 0) {
                return Result.success(null);
            } else {
                return Result.fail(500, "删除设备类型失败");
            }

        } catch (Exception e) {
            log.error("删除设备类型异常: {}", e.getMessage());
            return Result.fail(500, "系统错误");
        }
    }

    @Override
    public Result dashboardStats() {
        List<DeviceInfo> deviceInfos = deviceInfoMapper.selectList(null);
        List<Project> projects = projectMapper.selectList(null);
        List<LowerComputerVariable> lowerComputerVariables = lowerComputerVariableMapper.selectList(null);
        HashMap<String, Object> result = new HashMap<>();

        // 在线数量
        long onlineCount = deviceInfos.stream()
                .filter(device -> device.getStats() != null && device.getStats() == 1)
                .count();
        result.put("totalDevices", deviceInfos.size());
        result.put("onlineDevices", onlineCount);
        result.put("totalProjects", projects.size());
        result.put("collectingVariables", lowerComputerVariables.size());
        return Result.success(result);
    }

    @Override
    public Result projectDistribution() {
        List<Project> projects = projectMapper.selectList(null);
        List<DeviceInfo> deviceInfos = deviceInfoMapper.selectList(null);
        ArrayList<Object> result = new ArrayList<>();

        for (Project project : projects) {
            // 使用Stream快速统计当前项目的设备
            List<DeviceInfo> projectDevices = deviceInfos.stream()
                    .filter(device -> device.getProjectId() == project.getId())
                    .collect(Collectors.toList());

            long onlineCount = projectDevices.stream()
                    .filter(device -> device.getStats() != null && device.getStats() == 1)
                    .count();

            Map<String, Object> item = new HashMap<>();
            // 项目ID
            item.put("projectId", project.getId());
            // 项目名称
            item.put("projectName", project.getProjectName());
            // 项目下设备总数
            item.put("deviceCount", projectDevices.size());
            // 项目下在线设备数
            item.put("onlineCount", onlineCount);

            result.add(item);
        }

        return Result.success(result);
    }

    @Override
    public Result recentData() {
        List<LowerComputerVariable> lowerComputerVariables = lowerComputerVariableMapper.selectList(null);
//        List<DeviceDataSchema> deviceDataSchemas = deviceDataSchemaMapper.selectList(null);
        List<DeviceInfo> deviceInfos = deviceInfoMapper.selectList(null);
        List<Map<String, Object>> result = lowerComputerVariables.stream()
                // 时间排序
                .sorted((a, b) -> {
                    if (a.getUpdateTime() == null && b.getUpdateTime() == null) return 0;
                    if (a.getUpdateTime() == null) return 1;
                    if (b.getUpdateTime() == null) return -1;
                    return b.getUpdateTime().compareTo(a.getUpdateTime());
                })
                // 分10条
                .limit(10)
                // 返回map
                .map(data -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("id", data.getId());
                    item.put("deviceId", data.getDeviceId());
                    // 流式查询设备名称
                    String deviceName = deviceInfos.stream().filter(deviceInfo -> Objects.equals(deviceInfo.getId(), data.getDeviceId())).findFirst().map(DeviceInfo::getDeviceName).orElse("其他设备");
                    item.put("deviceName", deviceName); // 临时设备名称
                    item.put("dataName", data.getVariableName());
                    item.put("data", data.getCurrentValue());
                    item.put("unit", data.getUnit());

                    if (data.getUpdateTime() != null) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        item.put("updateTime", sdf.format(data.getUpdateTime()));
                    } else {
                        item.put("updateTime", "");
                    }

                    return item;
                })
                .collect(Collectors.toList());

        return Result.success(result);
    }

    @Override
    public Result deviceTypeByProject(Integer projectId) {
        try {
            // 检查参数
            if (projectId == null) {
                return Result.fail(400, "项目ID不能为空");
            }

            // 查询该项目的所有设备类型
            LambdaQueryWrapper<DeviceType> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DeviceType::getProjectId, projectId);
            List<DeviceType> deviceTypes = deviceTypeMapper.selectList(queryWrapper);

            // 构建返回数据
            List<Map<String, Object>> resultList = new ArrayList<>();
            for (DeviceType deviceType : deviceTypes) {
                Map<String, Object> item = new HashMap<>();
                item.put("id", deviceType.getId());
                item.put("projectId", deviceType.getProjectId());
                item.put("typeName", deviceType.getTypeName());
                resultList.add(item);
            }

            return Result.success(resultList);

        } catch (Exception e) {
            log.error("根据项目获取设备类型异常: {}", e.getMessage());
            return Result.fail(500, "系统错误");
        }
    }

    @Override
    public Result DeviceList(Integer projectId, Integer deviceTypeId, String deviceName, Integer pageNum, Integer pageSize) {
        try {
            // 设置默认分页参数
            if (pageNum == null || pageNum < 1) {
                pageNum = 1;
            }
            if (pageSize == null || pageSize < 1) {
                pageSize = 10;
            }

            // 构建查询条件
            LambdaQueryWrapper<DeviceInfo> queryWrapper = new LambdaQueryWrapper<>();

            // 添加项目ID筛选条件
            if (projectId != null) {
                queryWrapper.eq(DeviceInfo::getProjectId, projectId);
            }

            // 添加设备类型ID筛选条件
            if (deviceTypeId != null) {
                queryWrapper.eq(DeviceInfo::getDeviceType, deviceTypeId);
            }

            // 添加设备名称模糊搜索条件
            if (deviceName != null && !deviceName.trim().isEmpty()) {
                queryWrapper.like(DeviceInfo::getDeviceName, deviceName);
            }

            // 按创建时间倒序排列
            queryWrapper.orderByDesc(DeviceInfo::getCreateTime);

            // 执行分页查询
            Page<DeviceInfo> page = new Page<>(pageNum, pageSize);
            Page<DeviceInfo> devicePage = deviceInfoMapper.selectPage(page, queryWrapper);

            // 获取设备ID列表
            List<Integer> deviceIds = devicePage.getRecords().stream()
                    .map(DeviceInfo::getId)
                    .collect(Collectors.toList());

            // 查询设备分组映射
            Map<Integer, Integer> deviceGroupMap;
            if (!deviceIds.isEmpty()) {
                LambdaQueryWrapper<DeviceGroupMapping> mappingQueryWrapper = new LambdaQueryWrapper<>();
                mappingQueryWrapper.in(DeviceGroupMapping::getDeviceId, deviceIds);
                List<DeviceGroupMapping> mappings = deviceGroupMappingMapper.selectList(mappingQueryWrapper);

                // 构建设备ID到分组ID的映射
                deviceGroupMap = mappings.stream()
                        .collect(Collectors.toMap(
                                DeviceGroupMapping::getDeviceId,
                                DeviceGroupMapping::getGroupId,
                                (existing, replacement) -> existing // 如果存在重复，保留现有的
                        ));
            } else {
                deviceGroupMap = new HashMap<>();
            }

            // 为每个设备设置分组ID
            List<Map<String, Object>> deviceListWithGroup = devicePage.getRecords().stream().map(device -> {
                Map<String, Object> deviceMap = new HashMap<>();
                deviceMap.put("id", device.getId());
                deviceMap.put("projectId", device.getProjectId());
                deviceMap.put("deviceType", device.getDeviceType());
                deviceMap.put("hardwareAddress", device.getHardwareAddress());
                deviceMap.put("deviceName", device.getDeviceName());
                deviceMap.put("info", device.getInfo());
                deviceMap.put("stats", device.getStats());
                deviceMap.put("createTime", device.getCreateTime());
                // 添加分组ID，如果没有分组则为null
                deviceMap.put("groupId", deviceGroupMap.get(device.getId()));
                deviceMap.put("iccid", device.getIccid());
                return deviceMap;
            }).collect(Collectors.toList());

            // 构建响应数据
            Map<String, Object> resultData = new HashMap<>();
            resultData.put("list", deviceListWithGroup);
            resultData.put("total", devicePage.getTotal());
            resultData.put("pageNum", pageNum);
            resultData.put("pageSize", pageSize);
            return Result.success(resultData);

        } catch (Exception e) {
            log.error("获取设备列表失败: {}", e.getMessage(), e);
            return Result.fail(500, "获取设备列表失败");
        }
    }

//    @Override
//    public Result deviceDetail(Integer id) {
//        return null;
//    }


    /**
     * 获取设备所属的分组信息
     */
    private List<Map<String, Object>> getDeviceGroups(Integer deviceId) {
        try {
            // 查询设备分组关联关系
            QueryWrapper<DeviceGroupMapping> mappingWrapper = new QueryWrapper<>();
            mappingWrapper.eq("device_id", deviceId);
            List<DeviceGroupMapping> mappings = deviceGroupMappingMapper.selectList(mappingWrapper);

            if (mappings.isEmpty()) {
                return Collections.emptyList();
            }

            // 获取分组ID列表
            List<Integer> groupIds = mappings.stream()
                    .map(DeviceGroupMapping::getGroupId)
                    .collect(Collectors.toList());

            // 查询分组详细信息
            QueryWrapper<DeviceGroup> groupWrapper = new QueryWrapper<>();
            groupWrapper.in("id", groupIds);
            List<DeviceGroup> groups = deviceGroupMapper.selectList(groupWrapper);

            // 转换为Map列表
            return groups.stream().map(group -> {
                Map<String, Object> groupMap = new HashMap<>();
                groupMap.put("id", group.getId());
                groupMap.put("groupName", group.getGroupName());
                groupMap.put("projectId", group.getProjectId());
                groupMap.put("createTime", group.getCreateTime());
                return groupMap;
            }).collect(Collectors.toList());

        } catch (Exception e) {
            log.error("获取设备分组信息失败，设备ID: {}", deviceId, e);
            return Collections.emptyList();
        }
    }

    @Override
    public Result deviceTypeListAll(Integer projectId) {
        try {
            // 构建查询条件
            LambdaQueryWrapper<DeviceType> queryWrapper = new LambdaQueryWrapper<>();

            // 添加项目ID筛选条件
            if (projectId != null) {
                queryWrapper.eq(DeviceType::getProjectId, projectId);
            }

            // 按创建时间倒序排列
            queryWrapper.orderByDesc(DeviceType::getCreateTime);

            // 执行查询
            List<DeviceType> deviceTypeList = deviceTypeMapper.selectList(queryWrapper);

            // 构建简化的返回数据
//            List<Map<String, Object>> resultList = deviceTypeList.stream()
//                    .map(deviceType -> {
//                        Map<String, Object> typeMap = new HashMap<>();
//                        typeMap.put("id", deviceType.getId());
//                        typeMap.put("projectId", deviceType.getProjectId());
//                        typeMap.put("typeName", deviceType.getTypeName());
//                        return typeMap;
//                    })
//                    .collect(Collectors.toList());

            return Result.success(deviceTypeList);

        } catch (Exception e) {
            log.error("获取设备类型列表失败: {}", e.getMessage(), e);
            return Result.fail(500, "获取设备类型列表失败");
        }
    }

    @Override
    public Result projectListName() {
        try {
            LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(Project::getId, Project::getProjectName);

            List<Project> projectList = projectMapper.selectList(queryWrapper);

            return Result.success(projectList);

        } catch (Exception e) {
            log.error("获取项目列表失败", e);
            return Result.fail(500, "获取项目列表失败");
        }
    }





//    @Override
//    public Result historyData(Integer variableId, String startTime, String endTime, Integer interval, Integer limit) {
//        try {
//            // 参数校验
//            if (variableId == null) {
//                return Result.fail(400, "变量ID不能为空");
//            }
//            if (startTime == null || endTime == null) {
//                return Result.fail(400, "开始时间和结束时间不能为空");
//            }
//
//            // 设置默认值
//            if (limit == null || limit <= 0) {
//                limit = 1000;
//            }
//            if (interval == null || interval <= 0) {
//                interval = 60; // 默认60秒
//            }
//
//            // 1. 查询变量基本信息
//            DeviceDataSchema variable = deviceDataSchemaMapper.selectById(variableId);
//            if (variable == null) {
//                return Result.fail(404, "变量不存在");
//            }
//
//            // 2. 查询历史数据 - 使用数据库采样
//            List<Map<String, Object>> dataPoints;
//            if (interval > 0) {
//                // 使用数据库采样
//                dataPoints = deviceDataLogMapper.selectSampledData(variableId, startTime, endTime, interval, limit);
//            } else {
//                // 不使用采样，查询原始数据
//                QueryWrapper<DeviceDataLog> queryWrapper = new QueryWrapper<>();
//                queryWrapper.eq("device_data_schema_id", variableId)
//                        .ge("create_time", startTime)
//                        .le("create_time", endTime)
//                        .orderByAsc("create_time")
//                        .last("LIMIT " + limit);
//
//                List<DeviceDataLog> historyData = deviceDataLogMapper.selectList(queryWrapper);
//                dataPoints = historyData.stream().map(log -> {
//                    Map<String, Object> dataPoint = new HashMap<>();
//                    dataPoint.put("value", log.getData());
//                    dataPoint.put("timestamp", log.getCreateTime());
//                    return dataPoint;
//                }).collect(Collectors.toList());
//            }
//
//            // 3. 构建返回数据
//            Map<String, Object> result = new HashMap<>();
//
//            // 变量信息
//            Map<String, Object> variableInfo = new HashMap<>();
//            variableInfo.put("id", variable.getId());
//            variableInfo.put("variableName", variable.getDataName());
//            variableInfo.put("variableAddress", variable.getAddressName());
//            variableInfo.put("unit", variable.getUnit());
//            variableInfo.put("dataType", variable.getDataType());
//            result.put("variableInfo", variableInfo);
//            result.put("dataPoints", dataPoints);
//
//            return Result.success(result);
//
//        } catch (Exception e) {
//            log.error("查询历史数据失败", e);
//            return Result.fail(500, "查询历史数据失败: " + e.getMessage());
//        }
//    }

    @Override
    public Result dataStats(Integer variableId, String startTime, String endTime) {
        return null;
    }

    @Override
    public Result deviceStatus() {
        try {
            // 查询所有设备信息
            List<DeviceInfo> devices = deviceInfoMapper.selectList(null);

            // 转换为状态信息
            List<Map<String, Object>> statusList = devices.stream().map(device -> {
                Map<String, Object> status = new HashMap<>();
                status.put("deviceId", device.getId());
                status.put("deviceName", device.getDeviceName());

                // 根据stats字段判断状态：1在线 -> online, 0离线 -> offline
                String statusText = device.getStats() == 1 ? "online" : "offline";
                status.put("status", statusText);

                // 最后心跳时间 - 使用创建时间作为最后心跳时间（实际业务中应该有专门的心跳时间字段）
                // 这里可以根据实际业务调整，比如使用update_time字段
                status.put("lastHeartbeat", device.getCreateTime());

                // 信号强度 - 在线设备随机生成80-100，离线设备为0
                int signalStrength = device.getStats() == 1 ? (80 + new Random().nextInt(21)) : 0;
                status.put("signalStrength", signalStrength);

                return status;
            }).collect(Collectors.toList());

            return Result.success(statusList);

        } catch (Exception e) {
            log.error("获取设备状态信息失败", e);
            return Result.fail(500, "获取设备状态信息失败: " + e.getMessage());
        }
    }

//    @Override
//    public Result variableList(Integer typeId) {
//        try {
//            // 构建查询条件
//            QueryWrapper<DeviceTypeSchema> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("type_id", typeId);
//
//            // 执行查询
//            List<DeviceTypeSchema> variableList = deviceTypeSchemaMapper.selectList(queryWrapper);
//
//            // 返回成功结果
//            return Result.success(variableList);
//
//        } catch (Exception e) {
//            // 记录错误日志
//            log.error("获取设备类型变量列表失败，类型ID: {}", typeId, e);
//
//            // 返回失败结果
//            return Result.fail(500, "获取变量列表失败");
//        }
//    }

    @Override
    public Result getGroupList(Integer projectId, String groupName) {
        try {
            // 构建查询条件
            QueryWrapper<DeviceGroup> queryWrapper = new QueryWrapper<>();
            queryWrapper.orderByDesc("create_time");

            // 如果传入了项目ID，则按项目筛选
            if (projectId != null) {
                queryWrapper.eq("project_id", projectId);
            }

            // 如果传入了分组名称，则按名称模糊搜索
            if (!StringUtils.isEmpty(groupName)) {
                queryWrapper.like("group_name", groupName.trim());
            }

            // 查询分组列表
            List<DeviceGroup> groups = deviceGroupMapper.selectList(queryWrapper);

            // 转换为Map列表并设置设备数量
            List<Map<String, Object>> groupList = groups.stream().map(group -> {
                Map<String, Object> groupMap = new HashMap<>();
                groupMap.put("id", group.getId());
                groupMap.put("projectId", group.getProjectId());
                groupMap.put("groupName", group.getGroupName());
                groupMap.put("createTime", group.getCreateTime());
                groupMap.put("updateTime", group.getUpdateTime());

                // 查询该分组下的设备数量
                int deviceCount = getDeviceCountByGroupId(group.getId());
                groupMap.put("deviceCount", deviceCount);

                return groupMap;
            }).collect(Collectors.toList());

            return Result.success(groupList);

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(500, "获取分组列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result groupAdd(DeviceGroup deviceGroup) {
        try {
            // 参数验证
            if (deviceGroup == null) {
                return Result.fail(401,"分组信息不能为空");
            }

            if (deviceGroup.getProjectId() == null) {
                return Result.fail(401, "项目ID不能为空");
            }

            if (deviceGroup.getGroupName() == null || deviceGroup.getGroupName().isEmpty()) {
                return Result.fail(401,"分组名称不能为空");
            }

            // 检查分组名称是否重复（同一项目下）
            QueryWrapper<DeviceGroup> checkWrapper = new QueryWrapper<>();
            checkWrapper.eq("project_id", deviceGroup.getProjectId())
                    .eq("group_name", deviceGroup.getGroupName());
            Long existCount = deviceGroupMapper.selectCount(checkWrapper);
            if (existCount != null && existCount > 0) {
                return Result.fail(401,"该分组名称已存在");
            }

            // 设置创建和更新时间
            Timestamp now = new Timestamp(new Date().getTime());
            deviceGroup.setCreateTime(now);
            deviceGroup.setUpdateTime(now);

            // 插入数据库
            int result = deviceGroupMapper.insert(deviceGroup);

            if (result > 0) {
                return Result.success("新增分组成功");
            } else {
                return Result.fail(401,"新增分组失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(401, "新增分组失败: " + e.getMessage());
        }
    }

    @Override
    public Result groupUpdate(DeviceGroup deviceGroup) {
        try {
            // 参数验证
            if (deviceGroup == null) {
                return Result.fail(400, "分组信息不能为空");
            }

            if (deviceGroup.getId() == null) {
                return Result.fail(400, "分组ID不能为空");
            }

            if (deviceGroup.getGroupName() == null || deviceGroup.getGroupName().isEmpty()) {
                return Result.fail(400, "分组名称不能为空");
            }

            // 检查分组是否存在
            DeviceGroup existingGroup = deviceGroupMapper.selectById(deviceGroup.getId());
            if (existingGroup == null) {
                return Result.fail(404, "分组不存在");
            }

            // 检查分组名称是否重复（同一项目下，排除自身）
            QueryWrapper<DeviceGroup> checkWrapper = new QueryWrapper<>();
            checkWrapper.eq("project_id", existingGroup.getProjectId())
                    .eq("group_name", deviceGroup.getGroupName())
                    .ne("id", deviceGroup.getId());
            Long existCount = deviceGroupMapper.selectCount(checkWrapper);
            if (existCount != null && existCount > 0) {
                return Result.fail(400, "该分组名称已存在");
            }

            // 设置更新时间
            deviceGroup.setUpdateTime(new Timestamp(new Date().getTime()));

            // 更新数据库
            int result = deviceGroupMapper.updateById(deviceGroup);

            if (result > 0) {
                return Result.success( deviceGroup);
            } else {
                return Result.fail(500, "更新分组失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(500, "更新分组失败: " + e.getMessage());
        }
    }

    @Override
    public Result groupDelete(Integer id) {
        try {
            // 参数验证
            if (id == null) {
                return Result.fail(400, "分组ID不能为空");
            }

            // 检查分组是否存在
            DeviceGroup existingGroup = deviceGroupMapper.selectById(id);
            if (existingGroup == null) {
                return Result.fail(404, "分组不存在");
            }

            // 检查分组下是否有设备
            QueryWrapper<DeviceGroupMapping> mappingWrapper = new QueryWrapper<>();
            mappingWrapper.eq("group_id", id);
            Long deviceCount = deviceGroupMappingMapper.selectCount(mappingWrapper);
            if (deviceCount != null && deviceCount > 0) {
                return Result.fail(400, "该分组下存在设备，无法删除");
            }

            // 删除分组
            int result = deviceGroupMapper.deleteById(id);

            if (result > 0) {
                return Result.success("删除分组成功");
            } else {
                return Result.fail(500, "删除分组失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(500, "删除分组失败: " + e.getMessage());
        }
    }

    @Override
    public Result groupDeviceList(Integer groupId) {
        try {
            // 参数验证
            if (groupId == null) {
                return Result.fail(400, "分组ID不能为空");
            }

            // 检查分组是否存在
            DeviceGroup existingGroup = deviceGroupMapper.selectById(groupId);
            if (existingGroup == null) {
                return Result.fail(404, "分组不存在");
            }

            // 查询分组下的设备列表
            QueryWrapper<DeviceGroupMapping> mappingWrapper = new QueryWrapper<>();
            mappingWrapper.eq("group_id", groupId);
            List<DeviceGroupMapping> mappings = deviceGroupMappingMapper.selectList(mappingWrapper);

            // 如果没有设备，返回空列表
            if (mappings.isEmpty()) {
                return Result.success(Collections.emptyList());
            }

            // 获取设备ID列表
            List<Integer> deviceIds = mappings.stream()
                    .map(DeviceGroupMapping::getDeviceId)
                    .collect(Collectors.toList());

            // 查询设备详细信息
            QueryWrapper<DeviceInfo> deviceWrapper = new QueryWrapper<>();
            deviceWrapper.in("id", deviceIds);
            List<DeviceInfo> devices = deviceInfoMapper.selectList(deviceWrapper);

            // 转换为Map列表返回
            List<Map<String, Object>> deviceList = devices.stream().map(device -> {
                DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
                Map<String, Object> deviceMap = new HashMap<>();
                deviceMap.put("id", device.getId());
                deviceMap.put("deviceName", device.getDeviceName());
                deviceMap.put("hardwareAddress", device.getHardwareAddress());
                deviceMap.put("deviceType", device.getDeviceType());
                deviceMap.put("deviceTypeName", deviceType.getTypeName());
                deviceMap.put("projectId", device.getProjectId());
                deviceMap.put("stats", device.getStats());
                deviceMap.put("createTime", device.getCreateTime());
                return deviceMap;
            }).collect(Collectors.toList());

            return Result.success(deviceList);

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(500, "获取分组设备列表失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result addDeviceToGroup(AddDeviceToGroupVo addDeviceToGroupVo) {
        try {
            // 参数验证
            if (addDeviceToGroupVo == null) {
                return Result.fail(400, "参数不能为空");
            }

            Integer groupId = addDeviceToGroupVo.getGroupId();
            List<Integer> deviceIds = addDeviceToGroupVo.getDeviceIds();

            if (groupId == null) {
                return Result.fail(400, "分组ID不能为空");
            }

            if (deviceIds == null || deviceIds.isEmpty()) {
                return Result.fail(400, "设备ID列表不能为空");
            }

            // 检查分组是否存在
            DeviceGroup existingGroup = deviceGroupMapper.selectById(groupId);
            if (existingGroup == null) {
                return Result.fail(404, "分组不存在");
            }

            // 检查设备是否存在且属于同一项目
            QueryWrapper<DeviceInfo> deviceWrapper = new QueryWrapper<>();
            deviceWrapper.in("id", deviceIds);
            List<DeviceInfo> devices = deviceInfoMapper.selectList(deviceWrapper);

            if (devices.size() != deviceIds.size()) {
                return Result.fail(400, "部分设备不存在");
            }

            // 检查设备是否已经在该分组中
            QueryWrapper<DeviceGroupMapping> checkWrapper = new QueryWrapper<>();
            checkWrapper.eq("group_id", groupId)
                    .in("device_id", deviceIds);
            List<DeviceGroupMapping> existingMappings = deviceGroupMappingMapper.selectList(checkWrapper);

            if (!existingMappings.isEmpty()) {
                List<Integer> existingDeviceIds = existingMappings.stream()
                        .map(DeviceGroupMapping::getDeviceId)
                        .collect(Collectors.toList());
                return Result.fail(400, "设备ID " + existingDeviceIds + " 已在该分组中");
            }

            // 检查设备是否已经在其他分组中（一个设备只能在一个分组）
            QueryWrapper<DeviceGroupMapping> otherGroupWrapper = new QueryWrapper<>();
            otherGroupWrapper.in("device_id", deviceIds)
                    .ne("group_id", groupId);
            List<DeviceGroupMapping> otherGroupMappings = deviceGroupMappingMapper.selectList(otherGroupWrapper);

            if (!otherGroupMappings.isEmpty()) {
                List<Integer> otherGroupDeviceIds = otherGroupMappings.stream()
                        .map(DeviceGroupMapping::getDeviceId)
                        .distinct()
                        .collect(Collectors.toList());
                return Result.fail(400, "设备ID " + otherGroupDeviceIds + " 已在其他分组中，一个设备只能属于一个分组");
            }

            // 批量添加设备到分组
            List<DeviceGroupMapping> mappings = deviceIds.stream().map(deviceId -> {
                DeviceGroupMapping mapping = new DeviceGroupMapping();
                mapping.setGroupId(groupId);
                mapping.setDeviceId(deviceId);
                mapping.setCreateTime(new Timestamp(new Date().getTime()));
                return mapping;
            }).collect(Collectors.toList());

            // 批量插入
            for (DeviceGroupMapping mapping : mappings) {
                deviceGroupMappingMapper.insert(mapping);
            }


            // 获取该分组下的所有设备
            HashMap<String, List<DeviceInfo>> groupDevices = getGroupDevices(groupId);


//             对分组内设备做变量连接
            devices.forEach(device -> {
                DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
                // 如果插入的设备是mqtt设备
                if (deviceType.getDeviceType().equals("mqtt_screen")) {
                    groupAddMqttScreen(device.getId(), groupId, groupDevices.get("lowerComputer"));
                }

                // 如果插入的设备是屏幕设备
                else if (deviceType.getDeviceType().equals("screen")) {
                    groupAddScreen(device.getId(), groupDevices.get("lowerComputer"));
                }

                // 如果插入的设备是下位机设备
                else if (deviceType.getDeviceType().equals("lower_computer")) {
                    groupAddLowerComputer(device.getId(), groupId, groupDevices.get("screen"), groupDevices.get("mqttScreen"));
                }
            });
            return Result.success("添加设备到分组成功");

        } catch (Exception e) {
            throw new RuntimeException("添加设备到分组失败" + e.getMessage());
        }
    }

    // 如果增加的是mqtt屏幕
    private void groupAddMqttScreen(Integer mqttDeviceId, Integer groupId, List<DeviceInfo> groupDevices) {

        groupDevices.forEach(device -> {
            MqttScreenVariableMapping mqttScreenVariableMapping = new MqttScreenVariableMapping(null, mqttDeviceId, device.getId(), device.getProjectId(), groupId, "新的连接", true);
            // 插入连接
            mqttScreenVariableMappingMapper.insert(mqttScreenVariableMapping);

            // 每个设备查询它的变量
            List<LowerComputerVariable> lowerComputerVariables = lowerComputerVariableMapper.selectList(new QueryWrapper<LowerComputerVariable>().eq("device_id", device.getId()));

            // 添加到mqtt的变量中
            lowerComputerVariables.forEach(lowerComputerVariable -> {

                // 如果失败就循环一直到第10次
                for (int i = 0; i < 10; i++) {
                    try{
                        if (i >= 1){
                            mqttScreenVariableMappingVariableMapper.insert(new MqttScreenVariableMappingVariable(null, mqttScreenVariableMapping.getId(), mqttDeviceId, device.getId(), lowerComputerVariable.getVariableName() + "_" + i, lowerComputerVariable.getId()));
                        }else{
                            mqttScreenVariableMappingVariableMapper.insert(new MqttScreenVariableMappingVariable(null, mqttScreenVariableMapping.getId(), mqttDeviceId, device.getId(), lowerComputerVariable.getVariableName(), lowerComputerVariable.getId()));
                        }
                        break;
                    } catch (DuplicateKeyException e){
                        System.out.println("插入数据" + new MqttScreenVariableMappingVariable(null, mqttScreenVariableMapping.getId(), mqttDeviceId, device.getId(), lowerComputerVariable.getVariableName() + "_" + i, lowerComputerVariable.getId()));
                        log.info("重复了" + lowerComputerVariable.getVariableName() + "_" + (i+1));
                    }
                }
            });
        });
    }

    // 如果增加的是普通屏幕
    private void groupAddScreen(Integer deviceId, List<DeviceInfo> groupDevices) {
        groupDevices.forEach(device -> {
            ScreenConnection screenConnection = new ScreenConnection(null, deviceId, device.getProjectId(), device.getId(), "新连接", true);
            screenConnectionMapper.insert(screenConnection);
        });
    }

    // 如果增加的是下位机采集设备
    private void groupAddLowerComputer(Integer deviceId, Integer groupId, List<DeviceInfo> groupScreenDevices, List<DeviceInfo> groupMqttScreenDevices){

        // 下位机变量
        List<LowerComputerVariable> lowerComputerVariables = lowerComputerVariableMapper.selectList(new QueryWrapper<LowerComputerVariable>().eq("device_id", deviceId));

        // 在所有mqtt的设备中增加映射
        groupMqttScreenDevices.forEach(device -> {
            MqttScreenVariableMapping mqttScreenVariableMapping = new MqttScreenVariableMapping(null, device.getId(), deviceId,device.getProjectId(), groupId,  "新连接", true);
            mqttScreenVariableMappingMapper.insert(mqttScreenVariableMapping);

            // 将下位机变量插入mqtt映射表中
            lowerComputerVariables.forEach(lowerComputerVariable -> {

                // 如果失败就循环一直到第10次
                for (int i = 0; i < 10; i++) {
                    try{
                        if (i >= 1){
                            mqttScreenVariableMappingVariableMapper.insert(new MqttScreenVariableMappingVariable(null, mqttScreenVariableMapping.getId(), device.getId(), deviceId, lowerComputerVariable.getVariableName()+ "_" + i, lowerComputerVariable.getId()));
                        }else{
                            mqttScreenVariableMappingVariableMapper.insert(new MqttScreenVariableMappingVariable(null, mqttScreenVariableMapping.getId(), device.getId(), deviceId, lowerComputerVariable.getVariableName(), lowerComputerVariable.getId()));
                        }
                        break;
                    } catch (DuplicateKeyException e){
                        log.info("重复了，更改变量命名" + lowerComputerVariable.getVariableName() + "_" + (i+1));
                    }
                }

            });

        });

        // 在所有屏幕设备中增加映射
        groupScreenDevices.forEach(device -> {
            ScreenConnection screenConnection = new ScreenConnection(null, device.getId(), device.getProjectId(), deviceId, "新连接", true);
            screenConnectionMapper.insert(screenConnection);
        });
    }

    /**
     * 获取该分组下的所有下位机设备
     * @param groupId
     * @return
     */
    private HashMap<String, List<DeviceInfo>> getGroupDevices(Integer groupId) {


        // 2. 通过分组ID查询该分组下的所有设备
        List<DeviceGroupMapping> deviceGroupMappings = deviceGroupMappingMapper.selectList(
                new QueryWrapper<DeviceGroupMapping>()
                        .eq("group_id", groupId)
        );

        // 获取分组下的设备
        ArrayList<DeviceInfo> groupDevices = new ArrayList<>();
        deviceGroupMappings.forEach(deviceGroupMapping -> {
            DeviceInfo deviceInfo = deviceInfoMapper.selectById(deviceGroupMapping.getDeviceId());
            groupDevices.add(deviceInfo);
        });

        // 3. 过滤出下位机类型的设备
        List<DeviceInfo> lowerComputer = groupDevices.stream()
                .filter(device -> {
                    // 通过设备类型ID查询设备类型
                    DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
                    return deviceType != null && "lower_computer".equals(deviceType.getDeviceType());
                })
                .collect(Collectors.toList());
        List<DeviceInfo> screen = groupDevices.stream()
                .filter(device -> {
                    // 通过设备类型ID查询设备类型
                    DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
                    return deviceType != null && "screen".equals(deviceType.getDeviceType());
                })
                .collect(Collectors.toList());
        List<DeviceInfo> mqttScreen = groupDevices.stream()
                .filter(device -> {
                    // 通过设备类型ID查询设备类型
                    DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
                    return deviceType != null && "mqtt_screen".equals(deviceType.getDeviceType());
                })
                .collect(Collectors.toList());

        HashMap<String, List<DeviceInfo>> map = new HashMap<>();
        map.put("lowerComputer", lowerComputer);
        map.put("screen", screen);
        map.put("mqttScreen", mqttScreen);
        return map;
    }


    @Override
    @Transactional
    public Result removeDeviceFromGroup(Integer groupId, Integer deviceId) {
        try {
            // 参数验证
            if (groupId == null) {
                return Result.fail(400, "分组ID不能为空");
            }

            if (deviceId == null) {
                return Result.fail(400, "设备ID不能为空");
            }

            // 检查分组是否存在
            DeviceGroup existingGroup = deviceGroupMapper.selectById(groupId);
            if (existingGroup == null) {
                return Result.fail(404, "分组不存在");
            }

            // 检查设备是否存在
            DeviceInfo existingDevice = deviceInfoMapper.selectById(deviceId);
            if (existingDevice == null) {
                return Result.fail(404, "设备不存在");
            }

            // 检查设备是否在分组中
            QueryWrapper<DeviceGroupMapping> checkWrapper = new QueryWrapper<>();
            checkWrapper.eq("group_id", groupId)
                    .eq("device_id", deviceId);
            DeviceGroupMapping existingMapping = deviceGroupMappingMapper.selectOne(checkWrapper);

            if (existingMapping == null) {
                return Result.fail(400, "该设备不在分组中");
            }

            // 从分组中移除设备
            int result = deviceGroupMappingMapper.delete(checkWrapper);

            // 获取该分组下的所有设备
//            HashMap<String, List<DeviceInfo>> groupDevices = getGroupDevices(groupId);

            // 删除id下的映射
            deleteMapping(deviceId);

            if (result > 0) {
                return Result.success("从分组移除设备成功");
            } else {
                return Result.fail(500, "从分组移除设备失败");
            }

        } catch (Exception e) {
            throw new RuntimeException("从分组移除设备失败" + e.getMessage());
        }
    }

    // 删除id下的映射
    private void deleteMapping(Integer deviceId){
        // 通过设备类型判断是哪种
        String deviceType = deviceTypeMapper.selectById(deviceInfoMapper.selectById(deviceId).getDeviceType()).getDeviceType();

        // 如果是普通屏幕
        if (deviceType.equals("screen")){
            screenConnectionMapper.delete(new QueryWrapper<ScreenConnection>().eq("screen_id", deviceId));
        }

        // 如果是mqtt屏幕
        else if(deviceType.equals("mqtt_screen")){
            mqttScreenVariableMappingVariableMapper.delete(new QueryWrapper<MqttScreenVariableMappingVariable>().eq("screen_id", deviceId));
            mqttScreenVariableMappingMapper.delete(new QueryWrapper<MqttScreenVariableMapping>().eq("screen_id", deviceId));
        }

        // 如果是下位机
        else if (deviceType.equals("lower_computer")){
            mqttScreenVariableMappingVariableMapper.delete(new QueryWrapper<MqttScreenVariableMappingVariable>().eq("lower_computer_id", deviceId));
            mqttScreenVariableMappingMapper.delete(new QueryWrapper<MqttScreenVariableMapping>().eq("lower_computer_id", deviceId));
            screenConnectionMapper.delete(new QueryWrapper<ScreenConnection>().eq("lower_computer_id", deviceId));
        }
    }

    @Override
    public Result availableDevices(Integer groupId, Integer projectId) {
        try {
            // 参数验证
            if (groupId == null) {
                return Result.fail(400, "分组ID不能为空");
            }

            if (projectId == null) {
                return Result.fail(400, "项目ID不能为空");
            }

            // 检查分组是否存在
            DeviceGroup existingGroup = deviceGroupMapper.selectById(groupId);
            if (existingGroup == null) {
                return Result.fail(404, "分组不存在");
            }

            // 检查分组是否属于指定项目
            if (!existingGroup.getProjectId().equals(projectId)) {
                return Result.fail(400, "分组不属于指定项目");
            }

            // 查询所有已加入任何分组的设备ID
            QueryWrapper<DeviceGroupMapping> allMappingsWrapper = new QueryWrapper<>();
            allMappingsWrapper.select("DISTINCT device_id");
            List<DeviceGroupMapping> allMappings = deviceGroupMappingMapper.selectList(allMappingsWrapper);
            List<Integer> allGroupedDeviceIds = allMappings.stream()
                    .map(DeviceGroupMapping::getDeviceId)
                    .collect(Collectors.toList());

            // 查询该项目下未加入任何分组的设备
            QueryWrapper<DeviceInfo> deviceWrapper = new QueryWrapper<>();
            deviceWrapper.eq("project_id", projectId);

            if (!allGroupedDeviceIds.isEmpty()) {
                deviceWrapper.notIn("id", allGroupedDeviceIds);
            }

            List<DeviceInfo> availableDevices = deviceInfoMapper.selectList(deviceWrapper);

            // 转换为Map列表返回
            List<Map<String, Object>> deviceList = availableDevices.stream().map(device -> {
                Map<String, Object> deviceMap = new HashMap<>();
                deviceMap.put("id", device.getId());
                deviceMap.put("deviceName", device.getDeviceName());
                deviceMap.put("hardwareAddress", device.getHardwareAddress());
                deviceMap.put("deviceType", device.getDeviceType());

                // 获取设备类型名称
                if (device.getDeviceType() != null) {
                    DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
                    deviceMap.put("deviceTypeName", deviceType != null ? deviceType.getTypeName() : "-");
                } else {
                    deviceMap.put("deviceTypeName", "-");
                }

                deviceMap.put("stats", device.getStats());
                deviceMap.put("createTime", device.getCreateTime());
                return deviceMap;
            }).collect(Collectors.toList());

            return Result.success(deviceList);

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(500, "获取可添加设备列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result variableList(Integer deviceTypeId) {
        try {
            if (deviceTypeId == null) {
                return Result.fail(401, "设备类型ID不能为空");
            }

            QueryWrapper<DeviceTypeVariableTemplate> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("device_type_id", deviceTypeId);
            queryWrapper.orderByAsc("register_address");

            List<DeviceTypeVariableTemplate> variableList = deviceTypeVariableTemplateMapper.selectList(queryWrapper);

            // 转换为 VO 对象
            List<DeviceTypeVariableTemplateVo> voList = variableList.stream().map(variable -> {
                DeviceTypeVariableTemplateVo vo = new DeviceTypeVariableTemplateVo();
                vo.setId(variable.getId());
                vo.setDeviceTypeId(variable.getDeviceTypeId());
                vo.setVariableName(variable.getVariableName());
                vo.setSlaveAddress(variable.getSlaveAddress());

                // 计算显示地址 - 需要将位掩码转换为位索引
                Integer bitIndex = null;
                if (variable.getBitPosition() != null) {
                    // 将0-based的位掩码转换为1-based的位索引
                    bitIndex = ModbusAddressUtil.convertMaskToBitIndex(variable.getBitPosition());
                }

                // 计算显示地址
                vo.setShowAddress(ModbusAddressUtil.calculateShowAddress(
                        variable.getRegisterType(),
                        variable.getRegisterAddress(),
                        variable.getDataType(),
                        bitIndex  // 这里传位索引，不是位掩码
                ));

                vo.setDataType(variable.getDataType());
                vo.setByteOrder(variable.getByteOrder());
                vo.setScaleFactor(variable.getScaleFactor());
                vo.setUnit(variable.getUnit());
                vo.setIsSave(variable.getIsSave()); // isSave
                vo.setFrequency(variable.getFrequency());
                vo.setCreateTime(variable.getCreateTime());
                vo.setPort(variable.getPort());

                return vo;
            }).collect(Collectors.toList());

            return Result.success(voList);

        } catch (Exception e) {
            log.error("获取设备类型变量列表失败，设备类型ID: {}", deviceTypeId, e);
            return Result.fail(401, "获取变量列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result variableAdd(DeviceTypeVariableTemplateVo vo) {
        try {
            if (vo == null) {
                return Result.fail(400, "参数不能为空");
            }

            // 必填字段校验
            if (vo.getDeviceTypeId() == null) {
                return Result.fail(400, "设备类型ID不能为空");
            }
            if (StringUtils.isBlank(vo.getVariableName())) {
                return Result.fail(400, "变量名称不能为空");
            }
            if (vo.getSlaveAddress() == null) {
                return Result.fail(400, "从机地址不能为空");
            }
            if (vo.getShowAddress() == null) {
                return Result.fail(400, "显示地址不能为空");
            }
            if (StringUtils.isBlank(vo.getDataType())) {
                return Result.fail(400, "数据类型不能为空");
            }

            // 解析显示地址
            ModbusAddressUtil.RegisterInfo addressInfo;
            try {
                addressInfo = ModbusAddressUtil.parseShowAddress(vo.getShowAddress().toString());
            } catch (IllegalArgumentException e) {
                return Result.fail(400, e.getMessage());
            }

            // 验证数据类型与寄存器类型匹配
            try {
                ModbusAddressUtil.validateAddressAndDataType(
                        addressInfo.getRegisterType(),
                        vo.getDataType(),
                        addressInfo.getBitIndex()
                );
            } catch (IllegalArgumentException e) {
                return Result.fail(400, e.getMessage());
            }

            // 计算位掩码（0-based）
            Integer bitPosition = null;
            if (addressInfo.getIsBit() && addressInfo.getBitIndex() != null) {
                bitPosition = ModbusAddressUtil.convertBitIndexToMask(addressInfo.getBitIndex());
            }

            // 唯一性校验 - 变量名称
            QueryWrapper<DeviceTypeVariableTemplate> nameQueryWrapper = new QueryWrapper<>();
            nameQueryWrapper.eq("device_type_id", vo.getDeviceTypeId());
            nameQueryWrapper.eq("variable_name", vo.getVariableName());
            Long nameCount = deviceTypeVariableTemplateMapper.selectCount(nameQueryWrapper);
            if (nameCount > 0) {
                return Result.fail(400, "该设备类型下已存在同名变量");
            }

            // 唯一性校验 - 寄存器地址
            QueryWrapper<DeviceTypeVariableTemplate> addressQueryWrapper = new QueryWrapper<>();
            addressQueryWrapper.eq("device_type_id", vo.getDeviceTypeId());
            addressQueryWrapper.eq("slave_address", vo.getSlaveAddress());
            addressQueryWrapper.eq("register_address", addressInfo.getActualAddress());
            addressQueryWrapper.eq("register_type", addressInfo.getRegisterType());

            // 如果是位操作，检查位位置是否冲突
            if (addressInfo.getIsBit()) {
                addressQueryWrapper.eq("bit_position", bitPosition);
            } else {
                addressQueryWrapper.isNull("bit_position");
            }

            Long addressCount = deviceTypeVariableTemplateMapper.selectCount(addressQueryWrapper);
            if (addressCount > 0) {
                return Result.fail(400, "该从机地址和寄存器地址组合已存在");
            }

            // 转换为实体对象
            DeviceTypeVariableTemplate entity = new DeviceTypeVariableTemplate();
            entity.setDeviceTypeId(vo.getDeviceTypeId());
            entity.setVariableName(vo.getVariableName());
            entity.setSlaveAddress(vo.getSlaveAddress());
            entity.setRegisterAddress(addressInfo.getActualAddress());
            entity.setRegisterType(addressInfo.getRegisterType());
            entity.setDataType(vo.getDataType());
            entity.setByteOrder(vo.getByteOrder());
            entity.setScaleFactor(vo.getScaleFactor() != null ? vo.getScaleFactor() : BigDecimal.ONE);
            entity.setUnit(vo.getUnit());
            entity.setIsSave(vo.getIsSave() != null ? vo.getIsSave() : false);
            entity.setFrequency(vo.getFrequency() != null ? vo.getFrequency() : 60);
            entity.setCreateTime(new Timestamp(System.currentTimeMillis()));

            // 设置端口
            if (StringUtils.isNotBlank(vo.getPort())) {
                entity.setPort(vo.getPort());
            } else {
                entity.setPort("1");
            }

            // 设置位掩码（0-based）
            entity.setBitPosition(bitPosition);

            // 设置默认字节序
            if (StringUtils.isBlank(entity.getByteOrder())) {
                entity.setByteOrder(getDefaultByteOrder(entity.getDataType()));
            }

            int result = deviceTypeVariableTemplateMapper.insert(entity);
            if (result <= 0) {
                return Result.fail(500, "新增变量失败");
            }

            // 返回 VO 对象
            DeviceTypeVariableTemplateVo resultVo = convertToVo(entity);
            return Result.success(resultVo);

        } catch (Exception e) {
            log.error("新增设备类型变量失败: {}", e.getMessage(), e);
            return Result.fail(500, "新增变量失败: " + e.getMessage());
        }
    }

    /**
     * 转换为VO对象
     */
    private DeviceTypeVariableTemplateVo convertToVo(DeviceTypeVariableTemplate entity) {
        DeviceTypeVariableTemplateVo vo = new DeviceTypeVariableTemplateVo();
        vo.setId(entity.getId());
        vo.setDeviceTypeId(entity.getDeviceTypeId());
        vo.setVariableName(entity.getVariableName());
        vo.setSlaveAddress(entity.getSlaveAddress());

        // 计算显示地址
        Integer bitIndex = null;
        if (entity.getBitPosition() != null) {
            // 将0-based的位掩码转换为1-based的位索引
            bitIndex = ModbusAddressUtil.convertMaskToBitIndex(entity.getBitPosition());
        }

        vo.setShowAddress(ModbusAddressUtil.calculateShowAddress(
                entity.getRegisterType(),
                entity.getRegisterAddress(),
                entity.getDataType(),
                bitIndex
        ));

        vo.setDataType(entity.getDataType());
        vo.setByteOrder(entity.getByteOrder());
        vo.setScaleFactor(entity.getScaleFactor());
        vo.setUnit(entity.getUnit());
        vo.setIsSave(entity.getIsSave());
        vo.setFrequency(entity.getFrequency());
        vo.setCreateTime(entity.getCreateTime());
        vo.setPort(entity.getPort());
        vo.setBitPosition(entity.getBitPosition()); // 保持原始的位掩码

        return vo;
    }

    @Override
    public Result variableUpdate(DeviceTypeVariableTemplateVo vo) {
        try {
            if (vo == null) {
                return Result.fail(400, "参数不能为空");
            }

            // 必填字段校验
            if (vo.getId() == null) {
                return Result.fail(400, "变量ID不能为空");
            }
            if (vo.getDeviceTypeId() == null) {
                return Result.fail(400, "设备类型ID不能为空");
            }
            if (StringUtils.isBlank(vo.getVariableName())) {
                return Result.fail(400, "变量名称不能为空");
            }
            if (vo.getSlaveAddress() == null) {
                return Result.fail(400, "从机地址不能为空");
            }
            if (vo.getShowAddress() == null) {
                return Result.fail(400, "显示地址不能为空");
            }
            if (StringUtils.isBlank(vo.getDataType())) {
                return Result.fail(400, "数据类型不能为空");
            }

            // 检查数据是否存在
            DeviceTypeVariableTemplate existingEntity = deviceTypeVariableTemplateMapper.selectById(vo.getId());
            if (existingEntity == null) {
                return Result.fail(404, "变量不存在");
            }

            // 解析显示地址
            ModbusAddressUtil.RegisterInfo addressInfo;
            try {
                addressInfo = ModbusAddressUtil.parseShowAddress(vo.getShowAddress().toString());
            } catch (IllegalArgumentException e) {
                return Result.fail(400, e.getMessage());
            }

            // 验证数据类型与寄存器类型匹配
            try {
                ModbusAddressUtil.validateAddressAndDataType(
                        addressInfo.getRegisterType(),
                        vo.getDataType(),
                        addressInfo.getBitIndex()
                );
            } catch (IllegalArgumentException e) {
                return Result.fail(400, e.getMessage());
            }

            // 计算位掩码（0-based）
            Integer bitPosition = null;
            if (addressInfo.getIsBit() && addressInfo.getBitIndex() != null) {
                bitPosition = ModbusAddressUtil.convertBitIndexToMask(addressInfo.getBitIndex());
            }

            // 唯一性校验 - 变量名称（排除自身）
            QueryWrapper<DeviceTypeVariableTemplate> nameQueryWrapper = new QueryWrapper<>();
            nameQueryWrapper.eq("device_type_id", vo.getDeviceTypeId());
            nameQueryWrapper.eq("variable_name", vo.getVariableName());
            nameQueryWrapper.ne("id", vo.getId());
            Long nameCount = deviceTypeVariableTemplateMapper.selectCount(nameQueryWrapper);
            if (nameCount > 0) {
                return Result.fail(400, "该设备类型下已存在同名变量");
            }

            // 唯一性校验 - 寄存器地址（排除自身）
            QueryWrapper<DeviceTypeVariableTemplate> addressQueryWrapper = new QueryWrapper<>();
            addressQueryWrapper.eq("device_type_id", vo.getDeviceTypeId());
            addressQueryWrapper.eq("slave_address", vo.getSlaveAddress());
            addressQueryWrapper.eq("register_address", addressInfo.getActualAddress());
            addressQueryWrapper.eq("register_type", addressInfo.getRegisterType());

            // 如果是位操作，检查位位置是否冲突
            if (addressInfo.getIsBit()) {
                addressQueryWrapper.eq("bit_position", bitPosition);
            } else {
                addressQueryWrapper.isNull("bit_position");
            }

            addressQueryWrapper.ne("id", vo.getId());
            Long addressCount = deviceTypeVariableTemplateMapper.selectCount(addressQueryWrapper);
            if (addressCount > 0) {
                if (addressInfo.getIsBit()) {
                    return Result.fail(400, "该从机地址和寄存器位地址组合已存在");
                } else {
                    return Result.fail(400, "该从机地址和寄存器地址组合已存在");
                }
            }

            // 更新实体对象
            DeviceTypeVariableTemplate entity = new DeviceTypeVariableTemplate();
            entity.setId(vo.getId());
            entity.setDeviceTypeId(vo.getDeviceTypeId());
            entity.setVariableName(vo.getVariableName());
            entity.setSlaveAddress(vo.getSlaveAddress());
            entity.setRegisterAddress(addressInfo.getActualAddress());
            entity.setRegisterType(addressInfo.getRegisterType());
            entity.setDataType(vo.getDataType());
            entity.setByteOrder(vo.getByteOrder());
            entity.setScaleFactor(vo.getScaleFactor() != null ? vo.getScaleFactor() : BigDecimal.ONE);
            entity.setUnit(vo.getUnit());
            entity.setIsSave(vo.getIsSave() != null ? vo.getIsSave() : false);
            entity.setFrequency(vo.getFrequency() != null ? vo.getFrequency() : 60);

            // 设置端口
            if (StringUtils.isNotBlank(vo.getPort())) {
                entity.setPort(vo.getPort());
            } else {
                entity.setPort("1");
            }

            // 设置位掩码（0-based）
            entity.setBitPosition(bitPosition);

            // 保留原有值
            entity.setCreateTime(existingEntity.getCreateTime());

            // 设置默认字节序
            if (StringUtils.isBlank(entity.getByteOrder())) {
                entity.setByteOrder(getDefaultByteOrder(entity.getDataType()));
            }

            int result = deviceTypeVariableTemplateMapper.updateById(entity);
            if (result <= 0) {
                return Result.fail(500, "更新变量失败");
            }

            // 返回更新后的 VO 对象
            DeviceTypeVariableTemplate updatedEntity = deviceTypeVariableTemplateMapper.selectById(vo.getId());
            DeviceTypeVariableTemplateVo resultVo = convertToVo(updatedEntity);
            return Result.success(resultVo);

        } catch (Exception e) {
            log.error("更新设备类型变量失败: {}", e.getMessage(), e);
            return Result.fail(500, "更新变量失败: " + e.getMessage());
        }
    }

    // 辅助方法
    private boolean validateRegisterType(String registerType, String dataType) {
        if (registerType == null || dataType == null) return false;

        boolean isBoolType = "bool".equalsIgnoreCase(dataType);

        switch (registerType.toLowerCase()) {
            case "coil":
            case "discrete_input":
                // 线圈和离散输入只能是布尔类型
                return isBoolType;
            case "input_register":
                // 输入寄存器只能是数值类型（不能是布尔）
                return !isBoolType;
            case "holding_register":
                return true; // 保持寄存器支持所有类型
            default:
                return false;
        }
    }

    private String getDefaultByteOrder(String dataType) {
        if (dataType == null) return "ABCD";

        String lowerDataType = dataType.toLowerCase();
        if (lowerDataType.contains("float") || lowerDataType.contains("double") ||
                lowerDataType.contains("int32") || lowerDataType.contains("uint32")) {
            return "ABCD";
        } else {
            return "AB";
        }
    }

    @Override
    public Result variableDelete(Integer id) {
        try {
            // 参数校验
            if (id == null) {
                return Result.fail(400, "变量ID不能为空");
            }

            // 检查数据是否存在
            DeviceTypeVariableTemplate existingVariable = deviceTypeVariableTemplateMapper.selectById(id);
            if (existingVariable == null) {
                return Result.fail(404, "变量不存在");
            }

            // 执行删除操作
            int result = deviceTypeVariableTemplateMapper.deleteById(id);
            if (result <= 0) {
                return Result.fail(500, "删除变量失败");
            }

            return Result.success(null);

        } catch (Exception e) {
            log.error("删除设备类型变量失败，变量ID: {}", id, e);
            return Result.fail(500, "删除变量失败: " + e.getMessage());
        }
    }

    @Override
    public Result getMqttScreens(Integer projectId) {
        try {
            // 构建设备查询条件
            QueryWrapper<DeviceInfo> deviceQueryWrapper = new QueryWrapper<>();

            // 首先查询设备类型为MQTT屏幕的设备类型ID
            QueryWrapper<DeviceType> typeQueryWrapper = new QueryWrapper<>();
            typeQueryWrapper.eq("device_type", "mqtt_screen");
            List<DeviceType> mqttScreenTypes = deviceTypeMapper.selectList(typeQueryWrapper);

            if (mqttScreenTypes.isEmpty()) {
                return Result.success(new ArrayList<>());
            }

            // 获取MQTT屏幕设备类型ID列表
            List<Integer> mqttScreenTypeIds = mqttScreenTypes.stream()
                    .map(DeviceType::getId)
                    .collect(Collectors.toList());

            // 查询MQTT屏幕设备
            deviceQueryWrapper.in("device_type", mqttScreenTypeIds);

            if (projectId != null) {
                deviceQueryWrapper.eq("project_id", projectId);
            }

            List<DeviceInfo> mqttScreenDevices = deviceInfoMapper.selectList(deviceQueryWrapper);

            List<DeviceGroupMapping> deviceGroupMappings = deviceGroupMappingMapper.selectList(null);


            // 构建返回结果
            List<Map<String, Object>> resultList = new ArrayList<>();

            for (DeviceInfo device : mqttScreenDevices) {
                Map<String, Object> deviceMap = new HashMap<>();
                deviceMap.put("id", device.getId());
                deviceMap.put("deviceName", device.getDeviceName());
                deviceMap.put("hardwareId", device.getHardwareAddress());
                deviceMap.put("projectId", device.getProjectId());
                deviceMap.put("deviceType", device.getDeviceType());
                deviceMap.put("stats", device.getStats());
                deviceMap.put("info", device.getInfo());
                deviceMap.put("createTime", device.getCreateTime());
                Integer groupId = deviceGroupMappings.stream().filter(map -> map.getDeviceId().equals(device.getId())).map(DeviceGroupMapping::getGroupId).findFirst().orElse(null);
                deviceMap.put("groupId", groupId);
                resultList.add(deviceMap);
            }

            return Result.success(resultList);

        } catch (Exception e) {
            log.error("获取MQTT屏幕列表失败", e);
            return Result.fail(401,"获取MQTT屏幕列表失败");
        }
    }

    @Override
    public Result getNormalScreens() {
        List<ScreenConnection> screenConnections = screenConnectionMapper.selectList(null);
        HashMap<String, Object> result = new HashMap<>();
        ArrayList<HashMap> result2 = new ArrayList<>();
        screenConnections.forEach(mqttScreenVariableMapping -> {
            DeviceInfo deviceInfo = deviceInfoMapper.selectById(mqttScreenVariableMapping.getScreenId());
            // 屏幕id
            result.put("id", mqttScreenVariableMapping.getScreenId());
            // 设备名称
            result.put("deviceName", deviceInfo.getDeviceName());
            result.put("hardwareId", mqttScreenVariableMapping.getLowerComputerId());
            result.put("projectId", mqttScreenVariableMapping.getProjectId());
            result2.add(result);
        });
        return Result.success(result2);
    }

    @Override
    public Result getMqttMappings(Integer screenId, Integer groupId) {
        try {
            List<Map<String, Object>> result = new ArrayList<>();

            // 1. 根据groupId获取分组下的设备ID列表
            QueryWrapper<DeviceGroupMapping> groupWrapper = new QueryWrapper<>();
            groupWrapper.eq("group_id", groupId);
            List<DeviceGroupMapping> groupMappings = deviceGroupMappingMapper.selectList(groupWrapper);

            if (groupMappings.isEmpty()) {
                return Result.success(result);
            }

            List<Integer> deviceIds = groupMappings.stream()
                    .map(DeviceGroupMapping::getDeviceId)
                    .collect(Collectors.toList());

            // 2. 查询屏幕与这些设备的MQTT变量映射
            QueryWrapper<MqttScreenVariableMappingVariable> variableWrapper = new QueryWrapper<>();
            variableWrapper.eq("screen_id", screenId)
                    .in("lower_computer_id", deviceIds);
            List<MqttScreenVariableMappingVariable> variableMappings = mqttScreenVariableMappingVariableMapper.selectList(variableWrapper);

            // 3. 构建返回结果
            for (MqttScreenVariableMappingVariable variableMapping : variableMappings) {
                Map<String, Object> mappingData = new HashMap<>();

                // 基础映射信息
                mappingData.put("id", variableMapping.getId());
                mappingData.put("screenId", variableMapping.getScreenId());
                mappingData.put("deviceId", variableMapping.getLowerComputerId());
                mappingData.put("variableId", variableMapping.getLowerVariableId());
                mappingData.put("screenVariableName", variableMapping.getMqttVariableName());
                mappingData.put("groupId", groupId);
                mappingData.put("isSaved", true);

                // 获取变量原始信息
                LowerComputerVariable variable = lowerComputerVariableMapper.selectById(variableMapping.getLowerVariableId());
                if (variable != null) {
                    mappingData.put("originalName", variable.getVariableName());
                    mappingData.put("dataType", variable.getDataType());
                } else {
                    mappingData.put("originalName", "");
                    mappingData.put("dataType", "");
                }

                // 获取设备信息
                DeviceInfo device = deviceInfoMapper.selectById(variableMapping.getLowerComputerId());
                if (device != null) {
                    mappingData.put("deviceName", device.getDeviceName());
                }

                result.add(mappingData);
            }

            return Result.success(result);

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(500, "查询MQTT映射列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result variablesList(Integer page, Integer size, Integer deviceId, Integer projectId, Integer deviceTypeId) {
        try {
            QueryWrapper<LowerComputerVariable> queryWrapper = new QueryWrapper<>();

            // 构建查询条件
            if (deviceId != null) {
                queryWrapper.eq("device_id", deviceId);
            }

            if (projectId != null) {
                // 如果需要根据项目ID查询，需要关联设备表
                queryWrapper.inSql("device_id",
                        "SELECT id FROM device_info WHERE project_id = " + projectId);
            }

            if (deviceTypeId != null) {
                // 如果需要根据设备类型ID查询，需要关联设备表
                queryWrapper.inSql("device_id",
                        "SELECT id FROM device_info WHERE device_type = " + deviceTypeId);
            }

            // 添加排序条件，按创建时间倒序
            queryWrapper.orderByDesc("create_time");

            // 分页处理
            Page<LowerComputerVariable> pageInfo = new Page<>(page, size);
            Page<LowerComputerVariable> resultPage = lowerComputerVariableMapper.selectPage(pageInfo, queryWrapper);

            // 处理找到设备名字
            ArrayList<LowerComputerVariableVo> arrayList = new ArrayList<>();
            for (LowerComputerVariable lowerComputerVariable : resultPage.getRecords()) {
                Integer deviceId1 = lowerComputerVariable.getDeviceId();
                DeviceInfo deviceInfo = deviceInfoMapper.selectById(deviceId1);
                String deviceName = deviceInfo.getDeviceName();
                LowerComputerVariableVo lowerComputerVariableVo = new LowerComputerVariableVo();
                BeanUtils.copyProperties(lowerComputerVariable, lowerComputerVariableVo);
                lowerComputerVariableVo.setDeviceName(deviceName);

                // 计算显示地址 - 需要将位掩码转换为位索引
                Integer bitIndex = null;
                if (lowerComputerVariable.getBitPosition() != null) {
                    // 将0-based的位掩码转换为1-based的位索引
                    bitIndex = ModbusAddressUtil.convertMaskToBitIndex(lowerComputerVariable.getBitPosition());
                }

                // 使用ModbusAddressUtil计算显示地址
                String showAddress = ModbusAddressUtil.calculateShowAddress(
                        lowerComputerVariable.getRegisterType(),
                        lowerComputerVariable.getRegisterAddress(),
                        lowerComputerVariable.getDataType(),
                        bitIndex  // 这里传位索引，不是位掩码
                );

                lowerComputerVariableVo.setShowAddress(showAddress);
                arrayList.add(lowerComputerVariableVo);
            }

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", arrayList);
            result.put("total", resultPage.getTotal());
            result.put("page", page);
            result.put("size", size);
            result.put("pages", resultPage.getPages());

            return Result.success(result);

        } catch (Exception e) {
            log.error("查询设备变量列表失败", e);
            return Result.fail(500, "查询设备变量列表失败: " + e.getMessage());
        }
    }

    @Override
    public Result mappingList(Integer screenId, Integer groupId, Integer projectId) {

        QueryWrapper<MqttScreenVariableMapping> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("screen_id", screenId);
        queryWrapper.eq("group_id", groupId);
        if (projectId != null){
            queryWrapper.eq("project_id", projectId);
        }
        List<MqttScreenVariableMapping> variableMappings = mqttScreenVariableMappingMapper.selectList(queryWrapper);
        ArrayList<Object> list = new ArrayList<>();
        variableMappings.forEach(variableMapping -> {
            QueryWrapper<MqttScreenVariableMappingVariable> variableQueryWrapper = new QueryWrapper<>();
            variableQueryWrapper.eq("mapping_id", variableMapping.getId());

            // 查询 每个映射下的变量
            List<MqttScreenVariableMappingVariable> variables = mqttScreenVariableMappingVariableMapper.selectList(variableQueryWrapper);
            ArrayList<Map> arrayList = new ArrayList<>();
            variables.forEach(variableItem -> {
                // 变量名称
                LowerComputerVariable lowerComputerVariable = lowerComputerVariableMapper.selectById(variableItem.getLowerVariableId());
                // 返回的数据
                Map<String, Object> variablesMap = new HashMap<>();
                variablesMap.put("id", variableItem.getId());
                variablesMap.put("screenId", variableItem.getScreenId());
                variablesMap.put("lowerComputerId", variableItem.getLowerComputerId());
                variablesMap.put("mqttVariableName", variableItem.getMqttVariableName());
                variablesMap.put("lowerVariableId", variableItem.getLowerVariableId());
                variablesMap.put("originalName", lowerComputerVariable.getVariableName());
                variablesMap.put("dataType", lowerComputerVariable.getDataType());
                arrayList.add(variablesMap);
            });

            // 返回的Map
            Map<String, Object> result = new HashMap<>();
            result.put("id", variableMapping.getId());
            result.put("screenId", variableMapping.getScreenId());
            result.put("lowerComputerId", variableMapping.getLowerComputerId());
            result.put("projectId", variableMapping.getProjectId());
            result.put("connectionName", variableMapping.getConnectionName());
            result.put("isActive", variableMapping.getIsActive());
            result.put("variableMappings", arrayList);
            list.add(result);
        });
        return Result.success(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result mappingSave(MqttSaveVo variable) {
        try {

            // 参数验证
            if (variable.getScreenId() == null || variable.getLowerComputerId() == null ||
                    variable.getProjectId() == null || variable.getMqttVariableName() == null ||
                    variable.getLowerVariableId() == null) {
                return Result.fail(400, "必要参数不能为空");
            }

            // 1. 处理主映射表 (mqtt_screen_variable_mapping)
            MqttScreenVariableMapping mainMapping = handleMainMapping(variable);

            // 2. 处理变量映射表 (mqtt_screen_variable_mapping_variable)
            MqttScreenVariableMappingVariable result = handleVariableMapping(variable, mainMapping.getId());

            return Result.success(result);

        } catch (Exception e) {
            log.error("保存MQTT映射失败: {}", e.getMessage(), e);
            return Result.fail(500, "保存失败: " + e.getMessage());
        }
    }

    /**
     * 批量保存MQTT映射
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result mappingSaveBatch(MqttBatchSaveVo batchVo) {
        if (batchVo.getMappings() == null || batchVo.getMappings().isEmpty()) {
            return Result.fail(400, "映射列表不能为空");
        }

        int successCount = 0;
        int totalCount = batchVo.getMappings().size();
        List<String> errorMessages = new ArrayList<>();

        try {
            for (int i = 0; i < batchVo.getMappings().size(); i++) {
                MqttSaveVo variable = batchVo.getMappings().get(i);

                try {
                    // 参数验证
                    if (variable.getScreenId() == null || variable.getLowerComputerId() == null ||
                            variable.getProjectId() == null || variable.getMqttVariableName() == null ||
                            variable.getLowerVariableId() == null) {
                        errorMessages.add("第" + (i + 1) + "条记录：必要参数不能为空");
                        continue;
                    }

                    // 1. 处理主映射表
                    MqttScreenVariableMapping mainMapping = handleMainMapping(variable);

                    // 2. 处理变量映射表
                    handleVariableMapping(variable, mainMapping.getId());

                    successCount++;

                } catch (Exception e) {
                    String errorMsg = "第" + (i + 1) + "条记录保存失败: " + e.getMessage();
                    errorMessages.add(errorMsg);
                    log.error(errorMsg);
                }
            }

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("success", successCount > 0);
            result.put("savedCount", successCount);
            result.put("totalCount", totalCount);
            result.put("failedCount", totalCount - successCount);

            if (!errorMessages.isEmpty()) {
                result.put("errorMessages", errorMessages);
            }

            if (successCount == 0) {
                return Result.fail(400, "全部保存失败");
            } else if (successCount < totalCount) {
                return Result.success( result);
            } else {
                return Result.success(result);
            }

        } catch (Exception e) {
            log.error("批量保存MQTT映射失败: {}", e.getMessage(), e);
            return Result.fail(500, "批量保存失败: " + e.getMessage());
        }
    }

    /**
     * 删除MQTT映射
     * @param id 映射ID（变量映射表的ID）
     * @return 删除结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result mappingDelete(Integer id) {
        try {
            if (id == null) {
                return Result.fail(400, "映射ID不能为空");
            }

            // 1. 先查询变量映射记录是否存在
            MqttScreenVariableMappingVariable variableMapping = mqttScreenVariableMappingVariableMapper.selectById(id);
            if (variableMapping == null) {
                return Result.fail(404, "映射记录不存在");
            }

            // 2. 删除变量映射记录
            int deleteCount = mqttScreenVariableMappingVariableMapper.deleteById(id);
            if (deleteCount == 0) {
                return Result.fail(500, "删除变量映射失败");
            }

            // 3. 检查主映射记录是否还有其他变量映射
            Integer mappingId = variableMapping.getMappingId();
            QueryWrapper<MqttScreenVariableMappingVariable> countWrapper = new QueryWrapper<>();
            countWrapper.eq("mapping_id", mappingId);

            Long remainingCount = mqttScreenVariableMappingVariableMapper.selectCount(countWrapper);

            // 4. 如果没有其他变量映射，也删除主映射记录（可选，根据业务需求）
            if (remainingCount == 0) {
                mqttScreenVariableMappingMapper.deleteById(mappingId);
                log.info("删除空的主映射记录，ID: {}", mappingId);
            }

            log.info("删除MQTT映射成功，变量映射ID: {}, 主映射ID: {}", id, mappingId);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("deletedId", id);
            result.put("deletedMainMapping", remainingCount == 0);

            return Result.success(result);

        } catch (Exception e) {
            log.error("删除MQTT映射失败，ID: {}, 错误: {}", id, e.getMessage(), e);
            return Result.fail(500, "删除失败: " + e.getMessage());
        }
    }

    /**
     * 获取屏幕已绑定的设备列表
     * @param screenId 屏幕ID
     * @return 已绑定设备列表
     */
    @Override
    public Result boundDevices(Integer screenId) {
        try {
            if (screenId == null) {
                return Result.fail(400, "屏幕ID不能为空");
            }

            // 1. 查询该屏幕的所有主映射记录
            QueryWrapper<MqttScreenVariableMapping> mappingWrapper = new QueryWrapper<>();
            mappingWrapper.eq("screen_id", screenId);
            List<MqttScreenVariableMapping> mainMappings = mqttScreenVariableMappingMapper.selectList(mappingWrapper);

            if (mainMappings.isEmpty()) {
                return Result.success(Collections.emptyList());
            }

            // 2. 提取所有下位机设备ID
            List<Integer> deviceIds = mainMappings.stream()
                    .map(MqttScreenVariableMapping::getLowerComputerId)
                    .distinct()
                    .collect(Collectors.toList());

            // 3. 查询设备信息
            QueryWrapper<DeviceInfo> deviceWrapper = new QueryWrapper<>();
            deviceWrapper.in("id", deviceIds);
            List<DeviceInfo> devices = deviceInfoMapper.selectList(deviceWrapper);

            if (devices.isEmpty()) {
                return Result.success(Collections.emptyList());
            }

            // 4. 查询设备类型信息
            List<Integer> deviceTypeIds = devices.stream()
                    .map(DeviceInfo::getDeviceType)
                    .distinct()
                    .collect(Collectors.toList());

            QueryWrapper<DeviceType> typeWrapper = new QueryWrapper<>();
            typeWrapper.in("id", deviceTypeIds);
            List<DeviceType> deviceTypes = deviceTypeMapper.selectList(typeWrapper);

            // 5. 构建设备类型映射
            Map<Integer, String> deviceTypeMap = deviceTypes.stream()
                    .collect(Collectors.toMap(DeviceType::getId, DeviceType::getTypeName));

            // 6. 构建连接名称映射（从主映射中获取）
            Map<Integer, String> connectionNameMap = mainMappings.stream()
                    .collect(Collectors.toMap(
                            MqttScreenVariableMapping::getLowerComputerId,
                            MqttScreenVariableMapping::getConnectionName,
                            (existing, replacement) -> existing // 如果有重复，保留第一个
                    ));

            Map<Integer, Boolean> isActiveMap = mainMappings.stream()
                    .collect(Collectors.toMap(
                            MqttScreenVariableMapping::getLowerComputerId,
                            MqttScreenVariableMapping::getIsActive,
                            (existing, replacement) -> existing
                    ));

            // 7. 转换为DTO列表
            List<BoundDeviceDTO> result = devices.stream()
                    .map(device -> {
                        BoundDeviceDTO dto = new BoundDeviceDTO();
                        dto.setId(device.getId());
                        dto.setDeviceName(device.getDeviceName());
                        dto.setHardwareAddress(device.getHardwareAddress());
                        dto.setDeviceType(device.getDeviceType());
                        dto.setDeviceTypeName(deviceTypeMap.get(device.getDeviceType()));
                        dto.setConnectionName(connectionNameMap.get(device.getId()));
                        dto.setIsActive(isActiveMap.get(device.getId()));
                        return dto;
                    })
                    .collect(Collectors.toList());

            log.info("获取屏幕已绑定设备成功，屏幕ID: {}, 设备数量: {}", screenId, result.size());
            return Result.success(result);

        } catch (Exception e) {
            log.error("获取屏幕已绑定设备失败，屏幕ID: {}, 错误: {}", screenId, e.getMessage(), e);
            return Result.fail(500, "获取绑定设备失败: " + e.getMessage());
        }
    }

    /**
     * 绑定屏幕与设备关系
     * @param bindDTO 绑定参数
     * @return 绑定结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result bindDevice(BindDeviceDTO bindDTO) {
        try {
            // 参数验证
            if (bindDTO.getScreenId() == null || bindDTO.getDeviceId() == null || bindDTO.getProjectId() == null) {
                return Result.fail(400, "屏幕ID、设备ID和项目ID不能为空");
            }

            // 1. 验证屏幕是否存在且为MQTT屏幕类型
            DeviceInfo screen = deviceInfoMapper.selectById(bindDTO.getScreenId());
            if (screen == null) {
                return Result.fail(404, "屏幕设备不存在");
            }

            // 检查屏幕设备类型是否为MQTT屏幕
            DeviceType screenType = deviceTypeMapper.selectById(screen.getDeviceType());
            if (screenType == null || !"mqtt_screen".equals(screenType.getDeviceType())) {
                return Result.fail(400, "设备不是MQTT屏幕类型");
            }

            // 2. 验证下位机设备是否存在
            DeviceInfo device = deviceInfoMapper.selectById(bindDTO.getDeviceId());
            if (device == null) {
                return Result.fail(404, "下位机设备不存在");
            }

            // 3. 验证项目ID是否匹配
            if (!bindDTO.getProjectId().equals(screen.getProjectId()) ||
                    !bindDTO.getProjectId().equals(device.getProjectId())) {
                return Result.fail(400, "屏幕、设备和项目ID不匹配");
            }

            // 4. 检查是否已存在绑定关系
            QueryWrapper<MqttScreenVariableMapping> existWrapper = new QueryWrapper<>();
            existWrapper.eq("screen_id", bindDTO.getScreenId())
                    .eq("lower_computer_id", bindDTO.getDeviceId())
                    .eq("project_id", bindDTO.getProjectId());

            MqttScreenVariableMapping existingMapping = mqttScreenVariableMappingMapper.selectOne(existWrapper);

            if (existingMapping != null) {
                // 已存在绑定关系，更新连接信息
                boolean needUpdate = false;
                if (bindDTO.getConnectionName() != null &&
                        !bindDTO.getConnectionName().equals(existingMapping.getConnectionName())) {
                    existingMapping.setConnectionName(bindDTO.getConnectionName());
                    needUpdate = true;
                }
                if (bindDTO.getIsActive() != null &&
                        !bindDTO.getIsActive().equals(existingMapping.getIsActive())) {
                    existingMapping.setIsActive(bindDTO.getIsActive());
                    needUpdate = true;
                }

                if (needUpdate) {
                    mqttScreenVariableMappingMapper.updateById(existingMapping);
                    log.info("更新设备绑定关系，屏幕ID: {}, 设备ID: {}", bindDTO.getScreenId(), bindDTO.getDeviceId());
                }

                Map<String, Object> result = new HashMap<>();
                result.put("success", true);
                result.put("message", "设备已绑定，连接信息已更新");
                result.put("mappingId", existingMapping.getId());
                result.put("isNew", false);

                return Result.success(result);
            }

            // 5. 创建新的绑定关系
            MqttScreenVariableMapping newMapping = new MqttScreenVariableMapping();
            newMapping.setScreenId(bindDTO.getScreenId());
            newMapping.setLowerComputerId(bindDTO.getDeviceId());
            newMapping.setProjectId(bindDTO.getProjectId());
            newMapping.setConnectionName(bindDTO.getConnectionName() != null ?
                    bindDTO.getConnectionName() : generateDefaultConnectionName(device));
            newMapping.setIsActive(bindDTO.getIsActive() != null ? bindDTO.getIsActive() : true);

            int insertResult = mqttScreenVariableMappingMapper.insert(newMapping);

            if (insertResult > 0) {
                log.info("绑定屏幕设备成功，屏幕ID: {}, 设备ID: {}, 映射ID: {}",
                        bindDTO.getScreenId(), bindDTO.getDeviceId(), newMapping.getId());

                Map<String, Object> result = new HashMap<>();
                result.put("success", true);
                result.put("message", "设备绑定成功");
                result.put("mappingId", newMapping.getId());
                result.put("isNew", true);

                return Result.success(result);
            } else {
                throw new RuntimeException("插入绑定记录失败");
            }

        } catch (Exception e) {
            log.error("绑定屏幕设备失败，屏幕ID: {}, 设备ID: {}, 错误: {}",
                    bindDTO.getScreenId(), bindDTO.getDeviceId(), e.getMessage(), e);
            return Result.fail(500, "绑定失败: " + e.getMessage());
        }
    }

    @Override
    public Result saveDeviceVariable(LowerComputerVariableVo vo) {
        try {
            if (vo == null) {
                return Result.fail(400, "参数不能为空");
            }

            // 必填字段校验
            if (vo.getDeviceId() == null) {
                return Result.fail(400, "设备ID不能为空");
            }
            if (StringUtils.isBlank(vo.getVariableName())) {
                return Result.fail(400, "变量名称不能为空");
            }
            if (vo.getSlaveAddress() == null) {
                return Result.fail(400, "从站地址不能为空");
            }
            if (StringUtils.isBlank(vo.getShowAddress())) {
                return Result.fail(400, "显示地址不能为空");
            }
            if (StringUtils.isBlank(vo.getDataType())) {
                return Result.fail(400, "数据类型不能为空");
            }

            // 检查设备是否存在
            DeviceInfo deviceInfo = deviceInfoMapper.selectById(vo.getDeviceId());
            if (deviceInfo == null) {
                return Result.fail(400, "设备不存在");
            }

            // 解析显示地址
            ModbusAddressUtil.RegisterInfo addressInfo;
            try {
                addressInfo = ModbusAddressUtil.parseShowAddress(vo.getShowAddress());
            } catch (IllegalArgumentException e) {
                return Result.fail(400, e.getMessage());
            }

            // 验证数据类型与寄存器类型匹配
            try {
                ModbusAddressUtil.validateAddressAndDataType(
                        addressInfo.getRegisterType(),
                        vo.getDataType(),
                        addressInfo.getBitIndex()
                );
            } catch (IllegalArgumentException e) {
                return Result.fail(400, e.getMessage());
            }

            // 计算位掩码（0-based）
            Integer bitPosition = null;
            if (addressInfo.getIsBit() && addressInfo.getBitIndex() != null) {
                bitPosition = ModbusAddressUtil.convertBitIndexToMask(addressInfo.getBitIndex());
            }

            // 转换为实体对象
            LowerComputerVariable entity = new LowerComputerVariable();

            // 如果是更新，设置ID
            if (vo.getId() != null) {
                entity.setId(vo.getId());

                // 检查数据是否存在
                LowerComputerVariable existing = lowerComputerVariableMapper.selectById(vo.getId());
                if (existing == null) {
                    return Result.fail(404, "变量不存在");
                }
            }

            entity.setDeviceId(vo.getDeviceId());
            entity.setVariableName(vo.getVariableName());
            entity.setPort(StringUtils.isNotBlank(vo.getPort()) ? vo.getPort() : "1");
            entity.setSlaveAddress(vo.getSlaveAddress());
            entity.setRegisterAddress(addressInfo.getActualAddress());
            entity.setRegisterType(addressInfo.getRegisterType());
            entity.setDataType(vo.getDataType());
            entity.setBitPosition(bitPosition);
            entity.setByteOrder(StringUtils.isNotBlank(vo.getByteOrder()) ? vo.getByteOrder() : "big_endian");
            entity.setScaleFactor(vo.getScaleFactor() != null ? vo.getScaleFactor() : BigDecimal.ONE);
            entity.setUnit(vo.getUnit());
            entity.setIsSave(vo.getIsSave() != null ? vo.getIsSave() : false);
            entity.setFrequency(vo.getFrequency() != null ? vo.getFrequency() : 60);
            entity.setCurrentValue(vo.getCurrentValue());
            entity.setUpdateTime(new Timestamp(System.currentTimeMillis()));

            if (vo.getId() == null) {
                entity.setCreateTime(new Timestamp(System.currentTimeMillis()));
            }

            // 唯一性校验
            Result validationResult = validateVariableUniqueness(entity, vo.getId() != null);
            if (!validationResult.isSuccess()) {
                return validationResult;
            }

            // 保存数据
            int result;
            if (vo.getId() != null) {
                result = lowerComputerVariableMapper.updateById(entity);
            } else {
                result = lowerComputerVariableMapper.insert(entity);
            }

            if (result <= 0) {
                return Result.fail(500, "保存变量失败");
            }

            // 返回保存后的数据
            LowerComputerVariable savedEntity;
            if (vo.getId() != null) {
                savedEntity = entity;
            } else {
                savedEntity = lowerComputerVariableMapper.selectById(entity.getId());
            }

            LowerComputerVariableVo resultVo = convertToVo(savedEntity);
            return Result.success(resultVo);

        } catch (Exception e) {
            log.error("保存设备变量失败: {}", e.getMessage(), e);
            return Result.fail(500, "保存变量失败: " + e.getMessage());
        }
    }

    // 在 LowerComputerVariableServiceImpl 中实现
    @Override
    public Result deleteDeviceVariable(Integer id) {
        try {
            if (id == null) {
                return Result.fail(400, "变量ID不能为空");
            }

            // 检查变量是否存在
            LowerComputerVariable variable = lowerComputerVariableMapper.selectById(id);
            if (variable == null) {
                return Result.fail(404, "变量不存在");
            }

            // 检查变量是否被MQTT映射使用
            boolean isUsedInMqttMapping = checkVariableUsedInMqttMapping(id);
            if (isUsedInMqttMapping) {
                return Result.fail(400, "该变量已被MQTT屏幕映射使用，无法删除");
            }

            // 执行删除
            int result = lowerComputerVariableMapper.deleteById(id);
            if (result <= 0) {
                return Result.fail(500, "删除变量失败");
            }

            return Result.success("删除成功");

        } catch (Exception e) {
            log.error("删除设备变量失败，变量ID: {}", id, e);
            return Result.fail(500, "删除变量失败: " + e.getMessage());
        }
    }



    /**
     * 检查变量是否被MQTT映射使用
     */
    private boolean checkVariableUsedInMqttMapping(Integer variableId) {
        try {
            // 查询 mqtt_screen_variable_mapping_variable 表中是否使用了该变量
            QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("lower_variable_id", variableId);

            // 这里需要根据您的实际表结构来查询
            // 假设您有一个 MqttScreenVariableMappingVariableMapper
            // Long count = mqttScreenVariableMappingVariableMapper.selectCount(queryWrapper);
            // return count > 0;

            // 暂时返回false，您需要根据实际表结构实现这个检查
            return false;

        } catch (Exception e) {
            log.error("检查变量使用情况失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 验证变量唯一性
     */
    private Result validateVariableUniqueness(LowerComputerVariable entity, boolean isUpdate) {
        // 唯一性校验 - 变量名称
        QueryWrapper<LowerComputerVariable> nameQueryWrapper = new QueryWrapper<>();
        nameQueryWrapper.eq("device_id", entity.getDeviceId());
        nameQueryWrapper.eq("variable_name", entity.getVariableName());
        if (isUpdate) {
            nameQueryWrapper.ne("id", entity.getId());
        }
        Long nameCount = lowerComputerVariableMapper.selectCount(nameQueryWrapper);
        if (nameCount > 0) {
            return Result.fail(400, "该设备下已存在同名变量");
        }

        // 唯一性校验 - 寄存器地址
        QueryWrapper<LowerComputerVariable> addressQueryWrapper = new QueryWrapper<>();
        addressQueryWrapper.eq("device_id", entity.getDeviceId());
        addressQueryWrapper.eq("slave_address", entity.getSlaveAddress());
        addressQueryWrapper.eq("register_address", entity.getRegisterAddress());
        addressQueryWrapper.eq("register_type", entity.getRegisterType());

        // 如果是位操作，检查位位置是否冲突
        if (entity.getBitPosition() != null) {
            addressQueryWrapper.eq("bit_position", entity.getBitPosition());
        } else {
            addressQueryWrapper.isNull("bit_position");
        }

        if (isUpdate) {
            addressQueryWrapper.ne("id", entity.getId());
        }

        Long addressCount = lowerComputerVariableMapper.selectCount(addressQueryWrapper);
        if (addressCount > 0) {
            return Result.fail(400, "该从站地址和寄存器地址组合已存在");
        }

        return Result.success(addressCount);
    }

    /**
     * 转换为VO对象
     */
    private LowerComputerVariableVo convertToVo(LowerComputerVariable entity) {
        LowerComputerVariableVo vo = new LowerComputerVariableVo();
        BeanUtils.copyProperties(entity, vo);

        // 设置设备名称
        DeviceInfo deviceInfo = deviceInfoMapper.selectById(entity.getDeviceId());
        if (deviceInfo != null) {
            vo.setDeviceName(deviceInfo.getDeviceName());
        }

        // 计算显示地址
        Integer bitIndex = null;
        if (entity.getBitPosition() != null) {
            bitIndex = ModbusAddressUtil.convertMaskToBitIndex(entity.getBitPosition());
        }

        vo.setShowAddress(ModbusAddressUtil.calculateShowAddress(
                entity.getRegisterType(),
                entity.getRegisterAddress(),
                entity.getDataType(),
                bitIndex
        ));

        return vo;
    }

    /**
     * 生成默认连接名称
     */
    private String generateDefaultConnectionName(DeviceInfo device) {
        return device.getDeviceName() + "_连接";
    }


    /**
     * 处理主映射表
     */
    private MqttScreenVariableMapping handleMainMapping(MqttSaveVo variable) {
        QueryWrapper<MqttScreenVariableMapping> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("screen_id", variable.getScreenId())
                .eq("lower_computer_id", variable.getLowerComputerId())
                .eq("project_id", variable.getProjectId());

        MqttScreenVariableMapping mainMapping = mqttScreenVariableMappingMapper.selectOne(queryWrapper);

        if (mainMapping == null) {
            // 创建新的主映射记录
            mainMapping = new MqttScreenVariableMapping();
            mainMapping.setScreenId(variable.getScreenId());
            mainMapping.setLowerComputerId(variable.getLowerComputerId());
            mainMapping.setProjectId(variable.getProjectId());
            mainMapping.setConnectionName(variable.getConnectionName());
            mainMapping.setIsActive(variable.getIsActive());

            mqttScreenVariableMappingMapper.insert(mainMapping);
            log.info("创建主映射记录成功，ID: {}", mainMapping.getId());
        } else {
            // 更新现有主映射记录
            if (variable.getConnectionName() != null) {
                mainMapping.setConnectionName(variable.getConnectionName());
            }
            if (variable.getIsActive() != null) {
                mainMapping.setIsActive(variable.getIsActive());
            }
            mqttScreenVariableMappingMapper.updateById(mainMapping);
            log.info("更新主映射记录成功，ID: {}", mainMapping.getId());
        }

        return mainMapping;
    }

    /**
     * 处理变量映射表
     */
    private MqttScreenVariableMappingVariable handleVariableMapping(MqttSaveVo variable, Integer mappingId) {
        MqttScreenVariableMappingVariable variableMapping;

        if (variable.getId() == null) {
            // 新增 - 检查是否已存在相同变量映射
            QueryWrapper<MqttScreenVariableMappingVariable> varQueryWrapper = new QueryWrapper<>();
            varQueryWrapper.eq("mapping_id", mappingId)
                    .eq("lower_variable_id", variable.getLowerVariableId());

            MqttScreenVariableMappingVariable existingVar = mqttScreenVariableMappingVariableMapper.selectOne(varQueryWrapper);

            if (existingVar != null) {
                throw new RuntimeException("该变量映射已存在");
            }

            // 创建新的变量映射
            variableMapping = new MqttScreenVariableMappingVariable();
            variableMapping.setMappingId(mappingId);
            variableMapping.setScreenId(variable.getScreenId());
            variableMapping.setLowerComputerId(variable.getLowerComputerId());
            variableMapping.setMqttVariableName(variable.getMqttVariableName());
            variableMapping.setLowerVariableId(variable.getLowerVariableId());

            mqttScreenVariableMappingVariableMapper.insert(variableMapping);
            log.info("新增变量映射成功，ID: {}", variableMapping.getId());

        } else {
            // 更新
            variableMapping = mqttScreenVariableMappingVariableMapper.selectById(variable.getId());
            if (variableMapping == null) {
                throw new RuntimeException("变量映射记录不存在，ID: " + variable.getId());
            }

            // 检查映射ID是否匹配
            if (!mappingId.equals(variableMapping.getMappingId())) {
                throw new RuntimeException("映射ID不匹配");
            }

            variableMapping.setMqttVariableName(variable.getMqttVariableName());
            variableMapping.setLowerVariableId(variable.getLowerVariableId());

            mqttScreenVariableMappingVariableMapper.updateById(variableMapping);
            log.info("更新变量映射成功，ID: {}", variableMapping.getId());
        }

        return variableMapping;
    }


    /**
     * 根据分组ID获取设备数量
     * @param groupId 分组ID
     * @return 设备数量
     */
    private int getDeviceCountByGroupId(Integer groupId) {
        QueryWrapper<DeviceGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", groupId);
        Long count = deviceGroupMapper.selectCount(queryWrapper);
        return count != null ? count.intValue() : 0;
    }


    @Override
    public Result deviceDetail(Integer id) {
        try {
            if (id == null) {
                return Result.fail(400, "设备ID不能为空");
            }

            // 1. 获取设备基本信息
            DeviceInfo deviceInfo = deviceInfoMapper.selectById(id);
            if (deviceInfo == null) {
                return Result.fail(404, "设备不存在");
            }

            Map<String, Object> result = new HashMap<>();

            // 2. 获取项目信息
            Project project = projectMapper.selectById(deviceInfo.getProjectId());

            // 3. 获取设备类型信息
            DeviceType deviceType = deviceTypeMapper.selectById(deviceInfo.getDeviceType());

            // 4. 获取设备分组信息
            List<Map<String, Object>> groups = getDeviceGroups(id);

            // 5. 获取设备变量统计信息
            Map<String, Object> statistics = getDeviceStatistics(id);

            // 6. 获取数据变量列表
            List<Map<String, Object>> dataSchemas = getDataSchemas(id);

            // 组装结果
            result.put("id", deviceInfo.getId());
            result.put("deviceName", deviceInfo.getDeviceName());
            result.put("hardwareAddress", deviceInfo.getHardwareAddress());
            result.put("projectName", project != null ? project.getProjectName() : "-");
            result.put("groups", groups);
            result.put("deviceTypeName", deviceType != null ? deviceType.getTypeName() : "-");
            result.put("createTime", deviceInfo.getCreateTime());
            result.put("info", deviceInfo.getInfo() != null ? deviceInfo.getInfo() : "-");
            result.put("statistics", statistics);
            result.put("dataSchemas", dataSchemas);

            return Result.success(result);

        } catch (Exception e) {
            log.error("获取设备详情失败，设备ID: {}", id, e);
            return Result.fail(500, "获取设备详情失败: " + e.getMessage());
        }
    }

    /**
     * 获取设备统计信息
     */
    private Map<String, Object> getDeviceStatistics(Integer deviceId) {
        Map<String, Object> statistics = new HashMap<>();

        // 获取所有变量
        QueryWrapper<LowerComputerVariable> wrapper = new QueryWrapper<>();
        wrapper.eq("device_id", deviceId);
        List<LowerComputerVariable> variables = lowerComputerVariableMapper.selectList(wrapper);

        // 总变量数
        statistics.put("totalVariables", variables.size());

        // 采集中变量数 (is_save = true)
        long collectingCount = variables.stream()
                .filter(var -> var.getIsSave() != null && var.getIsSave())
                .count();
        statistics.put("collectingVariables", (int) collectingCount);

        // 最后数据时间 (取最大的update_time)
        Optional<Timestamp> lastDataTime = variables.stream()
                .map(LowerComputerVariable::getUpdateTime)
                .filter(Objects::nonNull)
                .max(Timestamp::compareTo);
        statistics.put("lastDataTime", lastDataTime.orElse(null));

        return statistics;
    }

    /**
     * 获取数据变量列表
     */
    private List<Map<String, Object>> getDataSchemas(Integer deviceId) {
        QueryWrapper<LowerComputerVariable> wrapper = new QueryWrapper<>();
        wrapper.eq("device_id", deviceId);
        wrapper.orderByAsc("register_type", "register_address", "bit_position");
        List<LowerComputerVariable> variables = lowerComputerVariableMapper.selectList(wrapper);

        return variables.stream().map(variable -> {
            Map<String, Object> schema = new HashMap<>();
            schema.put("id", variable.getId());
            schema.put("dataName", variable.getVariableName());
            schema.put("dataType", variable.getDataType());
            schema.put("unit", variable.getUnit() != null ? variable.getUnit() : "");

            // 计算显示地址作为topic
            String showAddress = ModbusAddressUtil.calculateShowAddress(
                    variable.getRegisterType(),
                    variable.getRegisterAddress(),
                    variable.getDataType(),
                    "bool".equalsIgnoreCase(variable.getDataType()) ? variable.getBitPosition() + 1 : null
            );
            schema.put("topic", showAddress);

            // 采集状态：is_save为true表示采集
            schema.put("isCollected", variable.getIsSave() != null && variable.getIsSave() ? 1 : 0);
            schema.put("collectionFrequency", variable.getFrequency());
            schema.put("lastData", variable.getCurrentValue() != null ? variable.getCurrentValue() : "-");
            schema.put("lastUpdateTime", variable.getUpdateTime() != null ? variable.getUpdateTime() : "-");

            return schema;
        }).collect(Collectors.toList());
    }

}
